Search code examples
c#c++.netilsharpdx

How to call method on a pointer to a C++ object using OpCodes.Calli


When calling a method on a C++ object from .NET using the .calli IL-instruction, how do you resolve the pointer to the actual method you want to call? I realize that this is going to be platform dependant.

I know the excellent SharpDX library uses the .calli instruction extensively, and I have peeked at the code it generates, and the method pointer gets pulled out like this:

((void**)(*(void**)_nativePointer))[69]

where _nativePointer is a pointer to the object instance. It's then cast to a void** which is de-references, and then cast again to a void** which indexes into slot 69. I just can't figure out what exactly is going on here.


Solution

  • Calli opcode will only work with objects having a vtable but cannot be used with standard C++ methods (non virtuals). It also requires that objects follow the same ABI, thus this is working well with COM as it defines a standard ABI to access C++ objects. But this will not work with, for example, C++ multiple inheritance.

    In order to access plain C++ method on an object, you need to have a generated C wrapper that provides a plain C function for each C++ method where the first parameter is usually the instance of the C++ object and the following parameters are the parameters from the C++ method (Some wrapper, like CXXI, are sometimes able to link directly to C++ objects by following compilers ABI). So in order to make this bridge you can:

    • Develop your own C wrapper (A dynamic library DLL/so that is providing these functions translating calls to C++ object)
    • SWIG is typically used to automate this kind of C++/C# bridge.
    • There was also an attempt from some Mono folks to provide a C++ bridging called CXXI, but doesn't seem to be developed.