2016-06-01 3 views
1

У меня есть DLL (с ​​C++ подобный код):Как вызвать экземпляр класса C++ из firefox-addon/js-ctypes?

MyObject::MyObject(TYPEPERIPH typePeriph) { 
    m_TypePeriph = typePeriph; 
    //.. 
} 

CR MyObject::GetTypePeriph(TYPEPERIPH *typePeriph) const throw(MY_Exception) { 
    *typePeriph = m_TypePeriph; 
    //.. 
    return 0; 
} 

Что называется в C++, как и что:

MyObject MyObject((TYPEPERIPH)myTypePeriph); 
MyObject.GetTypePeriph(&result); 

Я хотел бы назвать эту DLL с js- ctypes:

Components.utils.import("resource://gre/modules/ctypes.jsm"); 
var dll = ctypes.open("my.dll"); 

var constructor = dll.declare('MyObject', 
    ctypes.default_abi, 
    ctypes.voidptr_t, 
    ctypes.uint8_t 
); 

var ptr=constructor(1) // ptr seems to be a pointer to an instance 

// but how to call this instance ?? should I pass the ptr somewhere ? 
var GetTypePeriph = dll.declare('GetTypePeriph', 
    ctypes.default_abi, 
    ctypes.int, 
    ctypes.uint8_t.ptr 
); 

var result=ctypes.uint8_t(0); 
GetTypePeriph(result.address()); 
myPerif= result.value; 

первая часть работы (^^) ... "PTR", как представляется, является допустимым указателем. Но я не могу понять, как вызвать метод экземпляра с этим указателем ...

ответ

1

Вы должны определить виртуальные таблицы затем создать экземпляр смотрите здесь - https://developer.mozilla.org/en-US/docs/Mozilla/js-ctypes/Examples/Using_COM_from_js-ctypes

Я также сделал некоторые COM только на прошлой неделе js-ctypes, я использовал DirectShow API для Windows - https://github.com/Noitidart/ostypes_playground/commits/audio-capture

Методы VTBLE ДОЛЖНЫ быть в порядке !! Мне потребовалось два месяца, чтобы понять, когда я впервые попал в нее.

Вот определения кучу COM вещей, которые я сделал: https://github.com/Noitidart/ostypes/compare/fb1b6324343d6e19c942bbc0eb46cfcfbe103f35...master

Я редактировал ваш код, чтобы выглядеть как он должен:

Components.utils.import("resource://gre/modules/ctypes.jsm"); 
var dll = ctypes.open("my.dll"); 

var MyConstructorVtbl = ctypes.StructType('MyConstructorVtbl'); 
var MyConstructor = ctypes.StructType('MyConstructor', [ 
    { 'lpVtbl': MyConstructorVtbl.ptr } 
]); 
MyConstructorVtbl.define([ 
    { 
     'GetTypePeriph': ctypes.FunctionType(ctyes.default_abi, 
      ctypes.int, [   // return type 
       MyConstructor.ptr, // arg 1 HAS to be ptr to the instance EVEN though your C++ above doesnt show this. this is how it works. 
       ctypes.uint8_t.ptr 
      ]).ptr 
    } 
]); 

var constructor = dll.declare('MyObject', 
    ctypes.default_abi, 
    MyConstructor.ptr.ptr, 
    ctypes.uint8_t 
); 

var ptr=constructor(1) // ptr seems to be a pointer to an instance 
var instance = ptr.contents.lpVtbl.contents; 

var result=ctypes.uint8_t(0); 
instance.GetTypePeriph(ptr, result.address()); 
myPerif= result.value; 
+0

Спасибо большое! это именно то, что нужно ... – manatlan

+1

Что касается порядка API в таблице vtable ... Должно ли оно соответствовать общедоступным методам класса? Мой .h начинается с конструктора, тогда деструктор, первый метод находится на третьем месте ... Должен ли я объявить их (конструктор и деструктор) тоже в vtable? заранее спасибо – manatlan

+0

Это потрясающий вопрос @manatlan - я не уверен. Если вы можете опробовать тест и сообщить мне, что это было бы здорово. Способ тестирования заключается в проверке возвращаемого значения функции, определенной в вашем ctypes vtable. Если это соответствует ожидаемому. Для теста вы можете заставить среднюю функцию возвращать '45' или что-то еще. Я знаю, что любые методы, которые ваш класс наследует, должны быть в порядке. Поэтому, если он наследует методы от того, что называется 'IUknown', вы смотрите на этот класс и сначала перечислите эти методы в том порядке, в котором они находятся в' IUnknown'. – Noitidart