charto / nbind

:sparkles: Magical headers that make your C++ library accessible from JavaScript :rocket:
MIT License
1.98k stars 119 forks source link

Passing vector of floating points value do not work with emscripten #96

Open Luthaf opened 6 years ago

Luthaf commented 6 years ago

Hi there !

I have another problem with emscripten compilation, which I extracted in a separated repository: https://github.com/Luthaf/nbind-vector-double.

The issue occurs when trying to pass std::vector<double> or std::vector<float> from C++ to JS. (The same happens with std::array<{float}, N>)

The code looks like this:

#include <vector>

struct Vector {
    static std::vector<float> floats() {
        return {{0.0, 1.0, 2.0}};
    }

    static std::vector<double> doubles() {
        return {{0.0, 1.0, 2.0}};
    }
};

#include "nbind/nbind.h"

NBIND_CLASS(Vector) {
    method(floats);
    method(doubles);
}

And on the JS side:

var assert = require('assert');
var nbind = require('nbind');
var lib = nbind.init().lib;

var floats = lib.Vector.floats();
console.log(floats);

var doubles = lib.Vector.doubles();
console.log(doubles);

assert(floats[0] == 0.0);
assert(floats[1] == 1.0);
assert(floats[2] == 2.0);

assert(doubles[0] == 0.0);
assert(doubles[1] == 1.0);
assert(doubles[2] == 2.0);

This prints

[ 0, 0, 0 ]
[ undefined, undefined, undefined ]

before failing the assertions.


I think the problem might be related to the code around here:

https://github.com/charto/nbind/blob/901a7d5129f9146b3a376d5feded5bb7ccbf0133/src/em/BindingStd.ts#L37-L40

because ptrSize will be 8 for double, which means that ptr will not be an integer but a real number with a decimal value of 0.5. But at the same time the issue might come from elsewhere, as the test also fails with floats (but differently ...)

Anyway, do you have an idea on how I could fix this ?