2013-04-07 41 views
11

Các Emscripten hướng dẫn cho một lời giải thích tốt về cách để tương tác với các chức năng C: https://github.com/kripken/emscripten/wiki/Interacting-with-codeTương tác với C lớp ++ trong Emscripten

Nhưng làm thế nào để bạn tương tác với các lớp học C++:

  • Gọi một constructor để tạo ra một đối tượng
  • Xóa một obj
  • Ngăn chặn loại bỏ mã chết của các lớp học và phương pháp của nó
+2

này nên được giải quyết sớm bởi 'embind'. Tôi nghĩ rằng bạn có thể có một cái nhìn tại https://github.com/kripken/emscripten/tree/master/tests/embind nhưng không chắc chắn nó hiện tại như thế nào. – abergmeier

+0

Tôi đã thấy nhận xét ở trên sau khi viết câu trả lời của tôi. Có vẻ như bây giờ có một số tài liệu về vấn đề này (https://github.com/imvu/emscripten/wiki/embind). Tôi sẽ xem xét sử dụng 'embind' khi tôi có cơ hội. – lakenen

+0

Lý do ngắn gọn này là khó khăn, google cho C++ tên mangling. – meawoppl

Trả lời

11

Kiểm tra này: https://github.com/kripken/emscripten/wiki/embind

Ví dụ:

C++:

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

mã JS:

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 :) Cảm ơn một triệu :) – Mortennobel

+0

Embind không hoạt động trên Emscripten 1.16.0 – FacePalm

6

Cách tôi làm điều này là tạo các hàm "proxy" để thực hiện các thao tác cần thiết. Ví dụ:

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

Sau đó, trong JS, bạn phải xây dựng một bản sao của đối tượng của bạn mà các cuộc gọi chức năng proxy (khó chịu, tôi biết, nhưng tôi không biết một giải pháp tốt hơn vào lúc này):

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

QUAN TRỌNG Hãy ghi nhớ, để cho tiện làm việc, bạn cần phải thêm cờ sau để lệnh EMCC của bạn để cho nó để không loại bỏ các phương pháp proxy mã chết (Chú ý: gạch dưới đây là cố ý và quan trọng!):

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

EDIT: Tôi đã tạo một gist để mọi người dùng thử mã.

+0

Cảm ơn - công việc tốt đẹp .. nhưng tôi đã hy vọng cho một giải pháp thanh lịch hơn ;-) – Mortennobel

+0

Vâng, cùng ở đây haha. Hãy cho tôi biết nếu bạn tìm thấy nó! :) – lakenen

Các vấn đề liên quan