gpt4 book ai didi

javascript - Emscripten Javascript接口(interface)实现

转载 作者:行者123 更新时间:2023-11-28 02:19:31 24 4
gpt4 key购买 nike

我需要更多关于如何在 javascript 中实现 emscripten 生成的类的信息。我在 c++ 中有以下接口(interface),但需要在 javascript 端实现它。

class OsHttp {
public:
virtual ~OsHttp() {}

virtual void request(const std::string & verb, const std::string & url, const std::string & body, const std::unordered_map<std::string, std::string> & headers, const std::shared_ptr<HttpCallback> & callback) = 0;
};

我知道下面的内容会让我开始,但我该如何实现构造函数等。

var osHttp = {
constructor: function(){}
request: function(verb, url, body, headers, callback) {
console.log('OsHttp with: ' + verb);
}
};

var OsHttpObject = Module.OsHttp.implement(osHttp);

最佳答案

如果我理解您的需求,那么您需要有某种方式在 Javascript 和 C++ 世界之间进行通信。另外,我认为如果你想使用一个在C++中实现这个接口(interface)的对象,那么要让它编译运行,就必须有一个C++中接口(interface)的具体实现。该接口(interface)的实现随后将调用 Javascript。

为此,您可以使用 EM_ASM_* macros在实现接口(interface)的类中:

class OsHttpImplementation : public OsHttp {
public:
~OsHttp()
{
EM_ASM({
// Cleanup anything in Javascript context
});
}

void request(const std::string & verb, const std::string & url, const std::string & body, const std::unordered_map<std::string, std::string> & headers, const std::shared_ptr<HttpCallback> & callback)
{
// Probably a good idea to save any shared pointers as members in C++
// so the objects they point to survive as long as you need them

int returnValue = EM_ASM_INT_V({
// Example ways of accessing data from C++
var verb = Pointer_stringify($0);
var url = Pointer_stringify($1);
var body = Pointer_stringify($2);
var callbackFunctionPointer = $3;

// Something here that makes an HTTP request, creates any objects, etc.

return 0;

}, verb.c_str(), url.c_str(), body.c_str(), callback.get());
}
};

如果您希望在 Javascript 中实际有一个对应于 C++ 对象的对象,您可能需要在 Javascript 中进行一些手动管理,以在某种工厂中创建/存储/删除对象。具体来说,它需要将它们存储在某个地方,以便 C++ 可以通过某种 key 访问正确的。指向“this”的指针可能很方便:

class OsHttpImplementation : public OsHttp {
public:
OsHttp()
{
EM_ASM_V({
var thisPointer = $0;
OsHttpFactory.construct(thisPointer);
}, this);
}

~OsHttp()
{
EM_ASM({
var thisPointer = $0;
OsHttpFactory.destruct(thisPointer);
}, this);
}

void request(const std::string & verb, const std::string & url, const std::string & body, const std::unordered_map<std::string, std::string> & headers, const std::shared_ptr<HttpCallback> & callback)
{
int returnValue = EM_ASM_INT_V({
var thisPointer = $0;
OsHttpFactory.get(thisPointer).request($1, $2, $3, $4);
}, this, verb.c_str(), url.c_str(), body.c_str(), callback.get());
}
};

在 Javascript 中实现 OsHttpFactory 有很大的自由度。你没有提到你是否想在浏览器中使用它,但如果你这样做了,并且正在使用 XMLHttpRequests,你可能会有类似的东西

(function(context) {

var store = {}

function OsHttp() {
this.request = null;
}

OsHttp.prototype.request = function(verb, url, body, callbackPointer) {
var request = this.request = new XMLHttpRequest();
request.onreadystatechange = function() {
if (request.readyState == 4) {
// Might need other arguments if you want to pass something back to C++
Module.Runtime.dynCall('v', callbackPointer, []);
}
});
this.request.open(verb, url, true);
this.request.send();
};

OsHttp.prototype.cleanup = function() {
// Do something to cleanup in-progress requests etc.
}

context.OsHttpFactory = {
construct: function(thisPointer) {
store[thisPointer] = new OsHttp();
},
destruct: function(thisPointer) {
store[thisPointer].cleanup();
delete store[thisPointer];
},
get: function(thisPointer) {
return store[thisPointer];
}
};

})(window);

然后在 C++ 中,您可以将它用作标准类:

// Run constructors
auto osHttp = new OsHttpImplementation();

// Make request
osHttp->request(....);

// Run destructors, and remove object from the Javascript store
delete osHttp;

我不得不说,这有点胡闹!

关于javascript - Emscripten Javascript接口(interface)实现,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33032317/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com