Question

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.

Was it helpful?

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.
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top