Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Converting a struct with std::vector of another struct with Emscripten

Introduction

I'm trying to convert the C++ code into wasm and javascript that is part of my project to display the feature descriptors points for NFT Image Tracking. My idea is to retrieve the data and store to a struct of vectors. The descriptors points are a collections of points in the 2d space.

Structure of the code

So i organized my code:

//the nftPoint struct store the value of each Feature descriptor point
struct nftPoint {
  int x;
  int y;
};

// in this struct i collect all the data the nftPoints are a vector of nftPoint
struct nftMarker {
  int widthNFT;
  int heightNFT;
  int dpiNFT;
  int numFsets;
  int numFpoints;
  int imgBWsize;
  int nftFeaturePoints;
  std::vector<nftPoint> nftPoints;
  int pointer;
};

i fill the data in this routine:

 for (int i=0; i<arc->num_F_points_NFT; i++){
      nft.nftPoints.push_back(nftPoint());
      nft.nftPoints[i].x = arc->F_points_NFT->coord[i].x;
      nft.nftPoints[i].y = arc->F_points_NFT->coord[i].y;
      ARLOGi("points x: %d\n", nft.nftPoints[i].x);
      ARLOGi("points y: %d\n", nft.nftPoints[i].y);
    }

And that's ok i can see all the points in the console.

Emscripten bindings

I have created my emscripten bindings in such way:

#include <emscripten/bind.h>

using namespace emscripten;

EMSCRIPTEN_BINDINGS(constant_bindings) {

  function("setup", &setup);
  function("_readNFTMarker", &readNFTMarker);

  value_object<nftMarker>("nftMarker")
  .field("width", &nftMarker::widthNFT)
  .field("height", &nftMarker::heightNFT)
  .field("dpi", &nftMarker::dpiNFT)
  .field("numFsets", &nftMarker::numFsets)
  .field("numFpoints", &nftMarker::numFpoints)
  .field("imgBWsize", &nftMarker::imgBWsize)
  .field("nftFeaturePoints", &nftMarker::nftFeaturePoints)
  .field("nftPoints", &nftMarker::nftPoints)
  .field("pointer", &nftMarker::pointer);

  value_array<nftPoint>("nftPoint")
  .element(&nftPoint::x)
  .element(&nftPoint::y);
  

  register_vector<nftPoint>("vector<nftPoint>");
}

i can compile my code without errors only this warning:

stderr: /home/walter/kalwalt-github/FeatureSET-Display/emscripten/ARimageFsetDisplay.cpp:101:13: warning: 'readNFTMarker' has C-linkage specified, but returns user-defined type 'nftMarker' which is incompatible with C [-Wreturn-type-c-linkage]
  nftMarker readNFTMarker(int id, std::string datasetPathname) {
            ^
1 warning generated.

Not expected result

but when i print the data in the browser console i get this:

{width: 893, height: 1117, dpi: 120, numFsets: 9, numFpoints: 165, …}
dpi: 120
height: 1117
imgBWsize: 3989924
nftFeaturePoints: 9298136
nftPoints: vector$nftPoint$
$$: {ptrType: RegisteredPointer, ptr: 9269272, count: {…}}
__proto__: ClassHandle
numFpoints: 165
numFsets: 9
pointer: 9300896
width: 893
__proto__: Object

Instead i would get the object nftPoints with an array of points. How should change my code to have this result instead? Any help will be highly appreciated, Thanks!

Walter

Repository of the code

If you want you can view my code on github, my repository is https://github.com/kalwalt/FeatureSET-Display and i am working on this PR

like image 373
kalwalt Avatar asked Aug 23 '26 13:08

kalwalt


1 Answers

If I got it right, your nftPoints property is not being mapped correctly when you pass it down C++ code.

What you can do instead of binding nftPoint as a value_array, you can try this instead:

value_object<nftPoint>("nftPoint")
    .field("x", &nftPoint::x)
    .field("y", &nftPoint::y);
    
register_vector<nftPoint>("nftPointVector");

To use this on the JS side, you need to push the items into the vector.

const nftPoints = [
    {x: 123, y: 345},
    {x: 232, y: 817}
];

const nftPointVector = new wasmModule.nftPointVector();
nftPoints.forEach(point => nftPointVector.push_back(point));

I've recently encountered a similar issue and wrote a blog post with more details. I hope it helps. https://ninkovic.dev/blog/2022/an-improved-guide-for-compiling-wasm-with-emscripten-and-embind

like image 103
Wizard Avatar answered Aug 26 '26 05:08

Wizard



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!