2013-04-07 7 views
11

Die Emscripten Tutorial eine gute Erklärung dafür, wie mit C-Funktionen zur Interaktion: https://github.com/kripken/emscripten/wiki/Interacting-with-codeInteraktion mit C++ Klassen in Emscripten

Aber wie interagieren Sie mit C++ Klassen:

  • Call a Konstruktor eine erstellen Objekt
  • oBJ
  • Prevent Beseitigung von totem Code der Klassen löschen und seine Methoden
+2

Dies sollte durch 'embind' in Angriff genommen bald werden. Ich denke, Sie können sich https://github.com/kripken/emscripten/tree/master/tests/embind ansehen, aber nicht sicher, wie aktuell es ist. – abergmeier

+0

Ich sah den obigen Kommentar nach dem Schreiben meiner Antwort. Sieht so aus, als gäbe es jetzt ein paar Dokumente (https://github.com/imvu/emscripten/wiki/embind). Ich werde mich mit 'embind' beschäftigen, wenn ich eine Chance bekomme. – lakenen

+0

Kurzer Grund das ist schwer, google für C++ Name Mangling. – meawoppl

Antwort

11

Check: https://github.com/kripken/emscripten/wiki/embind

Beispiel:

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

Awsome :) Danke eine Million :) – Mortennobel

+0

Embind funktioniert nicht auf Emscripten 1.16.0 – FacePalm

6

Die Art, wie ich dies tat war, um "Proxy" -Funktionen zu erstellen, die die notwendigen Operationen ausführen. Zum Beispiel:

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

dann in JS, haben Sie einen Klon des Objekts zu erstellen, die die Proxy-Funktionen aufrufen (ärgerlich, ich weiß, aber ich weiß nicht, von einer besseren Lösung im 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); 
}; 

WICHTIG Denken Sie daran, für diese, um zu arbeiten, müssen Sie das folgende Flag zu Ihrem emcc Befehl hinzufügen, um es zu sagen, nicht die Proxy-Methoden als toter Code Streifen aus (Hinweis: das Unterstreichungs hier ist beabsichtigt und wichtig!):

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

EDIT: Ich habe eine gist für Leute erstellt, um den Code auszuprobieren. diese

+0

Danke - nette Arbeit .. aber ich hatte auf eine elegantere Lösung gehofft ;-) – Mortennobel

+0

Ja, gleich hier haha. Lass es mich wissen, wenn du eins findest! :) – lakenen