Emscripten Javascript接口实现 [英] Emscripten Javascript interface implementation

查看:256
本文介绍了Emscripten Javascript接口实现的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要更多的信息,如何在javascript中实现emscripten生成的类。我在c ++中有以下界面,但需要在javascript端实现它。

I need a bit more information on how to implement emscripten generated classes in javascript. I have the following interface in c++ but need to implement it on the javascript side.

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

我知道以下会让我开始,但是如何实现构造函数等。 p>

I know that the following will get me started, but how do i implement the constructor etc.

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 ++中的对象,然后让它编译和运行,必须有一个具体的实现接口的C ++。这个接口的实现将调用Javascript。

If I'm understanding what you're after, then you need to have some way of communicating between the Javascript and C++ worlds. Also, I think that if you want to use an object that implements this interface in C++, then to get it to compile and run, there must be a concrete implementation of the interface in C++. This implementation of the interface would then call out to Javascript.

为了做到这一点,你可以使用 EM_ASM_ * macros 在实现接口的类中:

To do this, you could use the EM_ASM_* macros in a class that implements the 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());
    }
};

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

If you want there to actually be an object in Javascript that corresponds to the C++ object, you might have to do a bit of manual management in Javascript to create/store/delete objects in some sort of factory. Specifically, it would need to store them somewhere so the C++ can access the right one via some sort of key. The pointer to "this" could be handy for that:

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,你可以使用

You have a lot of freedom on the implementation of OsHttpFactory in Javascript. You haven't mentioned if you want this in a browser, but if you do, and are using XMLHttpRequests, you could have something like

(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 ++中你可以使用它作为一个标准类:

Then in C++ you could use it as a standard class:

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

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

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

我不得不说,这是一个faff!

I have to say, it's all a bit of a faff!

这篇关于Emscripten Javascript接口实现的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆