1

I have a C/C++ function that returns two arrays each the size that is unknown before the call. I need to call this function from JavaScript. (For simplicity, one array is returned in the example).

extern "C" {
  void produce_object_3d(float* verts, int *num_verts);
}

Note that JavaScript does not know std::vector and boost:array and other types. I currently pre-allocate some space, but it will not work. Here is the code on the JavaScript side:

var verts_address = Module._malloc(FLOAT_SIZE*3*max_verts);
var nv_address = Module._malloc(INT_SIZE*1);
//
produce_object_3d (verts_address, nv_address);
//
var nverts = Module.HEAPU32[nv_address/INT_SIZE];
var verts = Module.HEAPF32.subarray(verts_address/FLOAT_SIZE, verts_address/FLOAT_SIZE + 3*nverts);

This is not efficient. Also what if the size of the result is large and there is not enough memory pre-allocated?

Garf365
  • 3,619
  • 5
  • 29
  • 41
Sohail Si
  • 2,750
  • 2
  • 22
  • 36
  • 1
    There's no way that C interface works the way you describe, it should be `float **verts` so that the C code can allocate it at the size it needs. Otherwise you have to pre-allocate in C, too. – unwind Jun 13 '16 at 15:10
  • As I mentioned, std::vector will not be callable when it is compiled into JAvaScript using Emscripten. I tagged as C++ because I want to find a solution to these for my C++ code. I actually internally implemented it in C++ using `` and other classes, but the difficulty is with the JS-interface. – Sohail Si Jun 13 '16 at 15:13
  • may actually work: http://stackoverflow.com/questions/35494467/how-to-bridge-a-javascript-ragged-array-and-an-stdvectorstdvectort-obj?rq=1 But not suitable for getting the elements. – Sohail Si Jun 13 '16 at 15:24
  • 1
    @SohailSi Why wouldn't vector work? The embind implementation for vector gives you a .get(position) function. Is performance the reason? – Tarun Gehlaut Aug 07 '16 at 12:13
  • I didn't know about *embind*. I will try it. – Sohail Si Aug 08 '16 at 15:16

1 Answers1

2

For your particular case using embind is a better option. As per the official documentation

For convenience, embind provides factory functions to register std::vector (register_vector()) and std::map (register_map()) types:

EMSCRIPTEN_BINDINGS(stl_wrappers) {
    register_vector<int>("VectorInt");
    register_map<int,int>("MapIntInt");
}

The returned object has methods like .get() and .size()

Tarun Gehlaut
  • 1,292
  • 10
  • 16