javascriptc++firefox-addonjsctypes

How to call a C++ class instance from firefox-addon / js-ctypes?


I've got a DLL (with c++ code like that):

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

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

Which is called in C++, like that :

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

I'd like to call this DLL with 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;

The first part works (^^) ... "ptr" seems to be a valid pointer. But I can't figure out how to call the instance method with this pointer ...


Solution

  • You have to define the VTABLE then create an instance see here - https://developer.mozilla.org/en-US/docs/Mozilla/js-ctypes/Examples/Using_COM_from_js-ctypes

    I also did some COM just last week with js-ctypes, I was using the DirectShow API on Windows - https://github.com/Noitidart/ostypes_playground/commits/audio-capture

    The VTBLE methods MUST be in order!! That took me like two months to figure out when I first got into it.

    Here are the definitions of a bunch of COM stuff I did: https://github.com/Noitidart/ostypes/compare/fb1b6324343d6e19c942bbc0eb46cfcfbe103f35...master

    I edited your code to look more like it should:

    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;