3

In JavaScript I have a list of "lines", each of which consists of indefinite number of "points", each of which has a form of [x, y]. So it is a 3D ragged array. Now I need to pass it to my C++ code with the help from emscripten (embind). Here's declaration of the C++ function:

Eigen::MatrixXd f(const std::vector<std::vector<std::vector<double>>>& lines);

And I would like to get a list of lists ([[m11, m12],[m22, m22],...]) in JavaScript after calling f. How to write the binding code in this case (the stuff inside EMSCRIPTEN_BINDINGS, for example)?

UPDATE: I can now pass the JavaScript array to C++. The binding part is something like

typedef std::vector<double> Point;
typedef std::vector<Point> Line;
EMSCRIPTEN_BINDINGS(module) {
  register_vector<Line>("LineArray");
  register_vector<Point>("Line");
  register_vector<double>("Point");
  emscripten::function("f_wrapper", &f_wrapper);
}

where f_wrapper calls f but returns vector<vector<double>> instead of MatrixXd. Now the problem is that I can only get an empty JavaScript object after calling f_wrapper. The JavaScript is

var Module = require('./bind.js'); // the output of em++
var cppAllLines = new Module.LineArray();
// some initialization
var result = Module.f_wrapper(cppAllLines); // an empty "Line" object

Any ideas?

Ziyuan
  • 4,215
  • 6
  • 48
  • 77
  • [Related](http://stackoverflow.com/questions/33668485/eigen-and-stdvector/33669013). – Avi Ginsburg Feb 19 '16 at 04:43
  • @AviGinsburg It's the other way around. – Ziyuan Feb 19 '16 at 10:35
  • 1
    Can you clarify why you mean by "empty" Line object? Based on your code, I have just created a small test of passing a LineArray into a C++ function from Javascript, which returns a Line back, and the communication seems to work both ways. I'm using Emscripten 1.35.23-64bit. http://pastebin.com/9g8vJFc9 and http://pastebin.com/P0BmKY3K – Michal Charemza Feb 22 '16 at 15:40
  • @MichalCharemza Aha! I treated it as a JavaScript array and thus checked the values like `result.length` or `result[0]` but found nothing defined. I should have looked into `emscripten/bind.h` to see what `register_vector` really does. Now I can visit the content normally. If you can write the comment into an answer I would like to accept it. Thank you! – Ziyuan Feb 22 '16 at 21:48

1 Answers1

4

When passing an embound vector from a C++ function, such as

std::vector<std::vector<double>> f_wrapper(...);

to Javascript

var result = Module.f_wrapper(...);

The result object is not a Javascript array that implements length property or array-indexed access, so it can appear "empty" if using these to access its data.

But it does expose get and size functions to access the vector:

console.log('Back from C++', result.size(), result.get(0).get(1));

(The double get is because we're returning a vector of vectors)

For completeness, looking into the prototype of the object returned, it seems to expose the following functions.

  • get
  • push_back
  • resize
  • set
  • size

Slightly inconsistently it exposes get and set functions rather than an equivalent of the C++ at function. I suspect that it's not possible for an exactly equivalent function since at returns a reference which allows it to be used as a setter, which isn't possible in Javascript.

Michal Charemza
  • 25,940
  • 14
  • 98
  • 165