Introduction to the xInterop .NET bridge


With the .NET open source movement, there will be more and more .NET libraries available to the managed world, there will be also a trend of using .NET libraries from all other languages, not every one is willing to re-invent the wheels in their favorite languages.

The best language to bridge to the .NET world is C/C++. There are existing technologies which can be used to call into C# libraries.

1. C++/CLI

C++/CLI is a bridging language which can be used to integrate .NET libraries by creating C++/CLI bridging/wrapper classes being exposed to the native world. The effort of creating such C++/CLI bridging/wrapper class is still considerable if there are many .NET classes and methods, the amount of time spent on marshaling different data types depends on size of the library. Ultimately, using C++/CLI is a manual process and requires big effort and it is not error prone, in fact, one may make many errors if not being careful enough.

(1) Lots of work, it is less than re-writing the library, but still lots of work for manually trying to figure out how to marshal the data types.

2. Unmanaged Exports

By adding MSIL .export directive to the original .NET function(must be static) then reassemble into a mixed-mode DLL, Unmanaged Exports can export static functions. You can download the nuget package from here. The features provided by Unmanaged Exports is very limited, for one, you can only export static functions with limited data primitive type and string, secondly, you will have to write the corresponding C/C++ portion in order to call the exported static methods from the .NET assembly, developers must load the library dynamically by calling LoadLibrary because you won’t have a .lib file you can link to, you must also define the type of a function type which corresponding to each C# static method signature.

(1) Any .NET class can not be exposed to the native world directly.

(2) Developers are responsible for creating C/C++ function type and loading individual functions.

(3) .NET assembly must be pre-processed and made into mixed mode DLL.

3. COM

Developers can also create a .NET COM component to expose COM interface for the C/C++ code to access the .NET assembly via COM. All the traditional COM limitation applies here.

(1) NET COM component must be registered.

(2) Generic and Generic type instance can not be used in COM interface.

(3) Static methods of any class will have to be re-wrapped in a new class as instance methods.

(4) Existing .NET class can not be just exposed via interface.

4. Reverse PInvoke

Reverse PInvoke merely means it is the reversed platform invoke from native application to .NET managed assembly, it basically sets up the callback function from .NET by using delegate so that the native DLL can retrieve the function pointer and call back into the .NET assembly. There are a few links listed below, you may want to read it for further information.

(1) The features provided by Revers PInvoke is also very limited, only the data types supported by PInvoke may be supported by Reverse PInvoke. Array type is not supported, there is no way for the .NET to find out the size of an pointer passed from the native world without extra work.

(2) Only .NET static methods can be called by native application.

(3) .NET classes can not be exposed to native application via Reverse PInvoke.

(4) The type of function type corresponding to the .NET static methods must be defined by developers.

5. xInterop .NET bridge

What is xInterop .NET bridge.

It is an add-on feature to the existing xInterop NGen++ (which we will officially rename to xInterop .NET). xInterop .NET bridge automatically creates C++ DLL based on any given C# .NET assembly and export header files and lib file for the C++ DLL so that any native application can reference and use the DLL for further development. It supports the following features.

(1) Classes. It will bridge any classes and create corresponding C++ classes for accessing the .NET classes. All public methods, both static and instance methods can be called from the native world.

(2) Structs. It will bridge any classes and create corresponding C++ classes for accessing the .NET struct. All public methods, both static and instance methods can be called from the native world.

(3) Enums. It will create corresponding C++ enum for each C# .NET enum.

(4) Generic Instance Types. All public methods, both static and instance methods can be called from the native world.

(5) Event and Event Handlers.

(6) Properties

(7) Fields

(8) Inheritance architecture.

(9) Constants

(10) Interfaces

(11) Delegates

(12) All C++ classes are derived from NObject class so that the instance of any class can be referenced by using NObject.

much more.

We will detail each of the features in the next posts. Please continue reading.

Translate »