c++ - Pass pointer to std::vector to Javascript using Emscripten, and use it - Stack Overflow

I would like to create a std::vector (specifically, a std::vector<string>) in C++, and then pass

I would like to create a std::vector (specifically, a std::vector<string>) in C++, and then pass it (or rather, a pointer to it) to Javascript, in order to be able to access its data/functions from directly-written Javascript.

So far I can get the integer pointer:

vector<string> myVector;
myVector.push_back("First item");
myVector.push_back("Second item");

EM_ASM_ARGS({
  // Prints out an integer value of the pointer,
  // but I would like to access the object members/data 
  // of myVector
  console.log($0);
}, &myVector);

I have found information at .h.html#register_vector__cCP and .html#built-in-type-conversions about the register_vector function

#include <emscripten/bind.h>
EMSCRIPTEN_BINDINGS(Wrappers) {
  register_vector<std::string>("VectorString");
};

which can be used to create a new vector from the Javascript world:

var myVector = new Module.VectorString();

but I can't figure out how to use this to access vector that already exists in the C++ world.

If I try to use Module.Runtime.dynCall('v', $0, []); on the pointer, as in when passing function pointers, then I get an error:

Invalid function pointer '380' called with signature 'v'

I have tried a few different binations of signatures, and they all seem to fail (Which I'm not really surprised about: it's not really a function pointer I'm calling, but a pointer to an instance of an object)

I would like to create a std::vector (specifically, a std::vector<string>) in C++, and then pass it (or rather, a pointer to it) to Javascript, in order to be able to access its data/functions from directly-written Javascript.

So far I can get the integer pointer:

vector<string> myVector;
myVector.push_back("First item");
myVector.push_back("Second item");

EM_ASM_ARGS({
  // Prints out an integer value of the pointer,
  // but I would like to access the object members/data 
  // of myVector
  console.log($0);
}, &myVector);

I have found information at http://kripken.github.io/emscripten-site/docs/api_reference/bind.h.html#register_vector__cCP and http://kripken.github.io/emscripten-site/docs/porting/connecting_cpp_and_javascript/embind.html#built-in-type-conversions about the register_vector function

#include <emscripten/bind.h>
EMSCRIPTEN_BINDINGS(Wrappers) {
  register_vector<std::string>("VectorString");
};

which can be used to create a new vector from the Javascript world:

var myVector = new Module.VectorString();

but I can't figure out how to use this to access vector that already exists in the C++ world.

If I try to use Module.Runtime.dynCall('v', $0, []); on the pointer, as in https://stackoverflow./a/29319440/1319998 when passing function pointers, then I get an error:

Invalid function pointer '380' called with signature 'v'

I have tried a few different binations of signatures, and they all seem to fail (Which I'm not really surprised about: it's not really a function pointer I'm calling, but a pointer to an instance of an object)

Share Improve this question edited May 23, 2017 at 11:54 CommunityBot 11 silver badge asked Mar 29, 2015 at 10:09 Michal CharemzaMichal Charemza 27.1k14 gold badges111 silver badges186 bronze badges 2
  • I've edited this question to explain why it's not a duplicate of stackoverflow./a/29319440/1319998 . The solution there doesn't apply in this case: that was calling a C++ function pointer from Javascript, while this question is about is accessing members of an existing C++ object. – Michal Charemza Commented Mar 29, 2015 at 10:26
  • I've also edited the title of the one at stackoverflow./a/29319440/1319998 (it's my question) to hopefully better show why it's different. – Michal Charemza Commented Mar 29, 2015 at 10:33
Add a ment  | 

1 Answer 1

Reset to default 5

Using the reinterpret_cast trick from https://stackoverflow./a/27364643/1319998 you can add another constructor to the object returned from the register_vector factory that does nothing but converts an integer pointer to a vector<string>:

vector<string> *vectorFromIntPointer(uintptr_t vec) {
  return reinterpret_cast<vector<string> *>(vec);
}

EMSCRIPTEN_BINDINGS(Wrappers) {
  register_vector<string>("VectorString").constructor(&vectorFromIntPointer, allow_raw_pointers());
};

Then if you create a vector in C++ code, you can access in JS code by

  • Getting a pointer to it
  • Passing the pointer to JS code via EM_AMS_ARGS
  • In the JS Code, create a new Module.VectorString object passing in the pointer value to the constructor

As in the following code:

vector<string> myVector;
myVector.push_back("First item");
myVector.push_back("Second item");

EM_ASM_ARGS({
  var myVector = new Module.VectorString($0);
  // Prints "Second item"
  console.log(myVector.get(1));
}, &myVector);

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1745135527a4613181.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信