使用 Emscripten 将一个结构体与另一个结构体的 std::vector 进行转换

问题描述 投票:0回答:1

简介

我正在尝试将 C++ 代码转换为 wasm 和 javascript,这是我项目的一部分,用于显示 NFT 图像跟踪的特征描述符点。我的想法是检索数据并将其存储到向量结构中。描述符点是二维空间中点的集合。

代码结构

所以我组织了我的代码:

//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;
};

我在此例程中填写数据:

 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);
    }

没关系,我可以在控制台中看到所有点。

Emscripten 绑定

我已经以这种方式创建了我的 emscripten 绑定:

#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>");
}

我可以编译我的代码,没有错误,只有这个警告:

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.

不是预期的结果

但是当我在浏览器控制台中打印数据时,我得到了这个:

{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

相反,我会得到带有点数组的对象 nftPoints 。应该如何更改我的代码才能得到这个结果?任何帮助将不胜感激,谢谢!

沃尔特

代码存储库

如果您愿意,可以在 github 上查看我的代码,我的存储库是 https://github.com/kalwalt/FeatureSET-Display,我正在研究这个 PR

javascript c++ webassembly emscripten
1个回答
0
投票

如果我没猜错,那么当您将其传递给 C++ 代码时,您的

nftPoints
属性不会被正确映射。

除了将

nftPoint
绑定为
value_array
之外,您可以做什么,您可以尝试以下操作:

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

要在 JS 端使用它,您需要将项目推入向量中。

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

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

我最近遇到了类似的问题,并写了一篇博客文章提供了更多详细信息。我希望它有帮助。 https://ninkovic.dev/blog/2022/an-improved-guide-for-compiling-wasm-with-emscripten-and-embind

© www.soinside.com 2019 - 2024. All rights reserved.