Interaction with C++ classes in Emscripten

前端 未结 2 1398
我在风中等你
我在风中等你 2020-12-29 09:41

The Emscripten tutorial give a good explanation of how to interact with C functions: https://github.com/kripken/emscripten/wiki/Interacting-with-code

But how do you

相关标签:
2条回答
  • 2020-12-29 10:01

    The way I did this was to create "proxy" functions that do the necessary operations. For example:

    class HelloWorld
    {
        int x;
      public:
        HelloWorld() { x = 0; }
        ~HelloWorld() {}
        void setX(int v) { x = v; }
        int getX() { return x; }
        // ...
    };
    
    
    //compile using "C" linkage to avoid name obfuscation
    extern "C" {
      //constructor, returns a pointer to the HelloWorld object
      void *HW_constructor() {
        return new HelloWorld();
      }
    
      void HW_setX(HelloWorld *hw, int x) {
        hw->setX(x);
      }
    
      int HW_getX(HelloWorld *hw) {
        return hw->getX();
      }
    
      void HW_destructor(HelloWorld *hw) {
        delete hw;
      }
    };
    

    Then in JS, you have to build a clone of your object that calls the proxy functions (annoying, I know, but I don't know of a better solution at the moment):

    // get references to the exposed proxy functions
    var HW_constructor = Module.cwrap('HW_constructor', 'number', []);
    var HW_destructor = Module.cwrap('HW_destructor', null, ['number']);
    var HW_setX = Module.cwrap('HW_setX', null, ['number', 'number']);
    var HW_getX = Module.cwrap('HW_getX', 'number', ['number']);
    
    function HelloWorld() {
      this.ptr = HW_constructor();
    }
    
    HelloWorld.prototype.destroy = function () {
      HW_destructor(this.ptr);
    };
    
    HelloWorld.prototype.setX = function (x) {
      HW_setX(this.ptr, x);
    };
    
    HelloWorld.prototype.getX = function () {
      return HW_getX(this.ptr);
    };
    

    IMPORTANT Keep in mind, in order for this to work, you need to add the following flag to your emcc command to tell it to not strip out the proxy methods as dead code (NOTE: the underscore here is intentional and important!):

    emcc helloworld.cpp -o helloworld.js \
      -s EXPORTED_FUNCTIONS="['_HW_constructor','_HW_destructor','_HW_setX','_HW_getX']"
    

    EDIT: I created a gist for folks to try out the code.

    0 讨论(0)
  • 2020-12-29 10:04

    Check this : http://kripken.github.io/emscripten-site/docs/porting/connecting_cpp_and_javascript/embind.html

    Example :

    C++ code :

    #include <emscripten/bind.h>
    
    using namespace emscripten;
    
    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;
    };
    
    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)
            ;
    }
    

    JS code :

    var instance = new Module.MyClass(10, "hello");
    instance.incrementX();
    instance.x; // 12
    instance.x = 20; // 20
    Module.MyClass.getStringFromInstance(instance); // "hello"
    instance.delete();
    
    0 讨论(0)
提交回复
热议问题