调试学习wasm,emscripten的各种用法 js 与 C++ 的交互
1.下载 emsdk
2.安装 emsdk
3.创建cpp文件 比如说 main.cpp
4.使用embind 导出函数 导出类 导出vector 等等
示例代码如下:
#include <emscripten.h>
#include <emscripten/bind.h>
#include <string>
#include <vector>
using namespace emscripten;
// This is your routine C++ code
size_t MyStrLen(std::string inStr) {
return inStr.length();
}
std::string MyStr(std::string inStr) {
string str = inStr + "123";
return str;
}
// This is the extra code you need to write to expose your function to JS
EMSCRIPTEN_BINDINGS(my_module) {
emscripten::function("MyStrLen", &MyStrLen);
}
EMSCRIPTEN_BINDINGS(my_module_1) {
emscripten::function("MyStr", &MyStr);
}
//Embind classes
class MyClass {
public:
MyClass(int x, std::string y)
: x(x)
, y(y)
{}
void incrementX() {
++x;
}
int getX() const { return x; }
void setX(int x_) { x = x_; }
static std::string getStringFromInstance(const MyClass& instance) {
return instance.y;
}
private:
int x;
std::string y;
};
// Binding code
EMSCRIPTEN_BINDINGS(my_class_example) {
class_<MyClass>("MyClass")
.constructor<int, std::string>()
.function("incrementX", &MyClass::incrementX)
.property("x", &MyClass::getX, &MyClass::setX)
.class_function("getStringFromInstance", &MyClass::getStringFromInstance)
;
}
std::vector<int> returnVectorData () {
std::vector<int> v(10, 1);
return v;
}
std::map<int, std::string> returnMapData () {
std::map<int, std::string> m;
m.insert(std::pair<int, std::string>(10, "This is a string."));
return m;
}
EMSCRIPTEN_BINDINGS(module) {
function("returnVectorData", &returnVectorData);
function("returnMapData", &returnMapData);
// register bindings for std::vector<int> and std::map<int, std::string>.
register_vector<int>("vector<int>");
register_map<int, std::string>("map<int, string>");
}
int main()
{
EM_ASM({
var myStr = "TestString";
console.log(myStr);
var len = Module.MyStrLen(myStr);
console.log("len = ",len);
var str = Module.MyStr(myStr);
console.log("str = ",str);
});
// emcc src/main.cpp -o bin/function.html -s EXPORTED_FUNCTIONS="['_int_sqrt','_main']" --bind
EM_ASM({
var returnStr = "玄魂";
var bufferSize = lengthBytesUTF8(returnStr) + 1;
var buffer = _malloc(bufferSize);
stringToUTF8(returnStr, buffer, bufferSize);
var retPtr = Module._outName(buffer);
console.log(UTF8ToString(retPtr));
_free(buffer);
});
EM_ASM({
var instance = new Module.MyClass(10, "hello");
instance.incrementX();
instance.x; // 11
instance.x = 20; // 20
var str = Module.MyClass.getStringFromInstance(instance); // "hello"
console.log('instance.str = ',str);
instance.delete();
/* 这个用法更好,避免了closure rename的问题
var instance = new Module["MyClass"](10, "hello");
instance["incrementX"]();
instance["x"]; // 11
instance["x"] = 20; // 20
Module["MyClass"]["getStringFromInstance"](instance); // "hello"
instance.delete();
*/
});
EM_ASM({
var retVector = Module['returnVectorData']();
// vector size
var vectorSize = retVector.size();
// reset vector value
retVector.set(vectorSize - 1, 11);
// push value into vector
retVector.push_back(12);
// retrieve value from the vector
for (var i = 0; i < retVector.size(); i++) {
console.log("Vector Value: ", retVector.get(i));
}
// expand vector size
retVector.resize(20, 1);
var retMap = Module['returnMapData']();
// map size
var mapSize = retMap.size();
// retrieve value from map
console.log("Map Value: ", retMap.get(10));
// figure out which map keys are available
// NB! You must call `register_vector<key_type>`
// to make vectors available
var mapKeys = retMap.keys();
for (var i = 0; i < mapKeys.size(); i++) {
var key = mapKeys.get(i);
console.log("Map key/value: ", key, retMap.get(key));
}
// reset the value at the given index position
retMap.set(10, "OtherValue");
});
}
// 编译命令: emcc src/main.cpp bin/main.html --bind
然后在bin目录 执行 npx serve . 前提是安装了 node.js
或者使用 npm i http-server -g 全局安装http-server
然后执行 http-server -p 888 --cors
-p 表示端口
--cors 表示允许跨域
然后在chrome浏览器地址栏输入 localhost:888/main.html即可
本文介绍了如何使用emscripten将C++代码编译为WebAssembly(WASM),并利用embind在JavaScript中调用C++函数、类及容器。通过示例展示了导出函数、类、vector和map的方法,并提供了一个简单的运行流程,包括编译命令和本地服务器设置。
2521

被折叠的 条评论
为什么被折叠?



