xInterop C++ .NET Bridge 4.0 is available now

xInterop C++ .NET Bridge 4.0 is available now

We are pleased to announce the release of xInterop C++ .NET Bridge 4.0, a Code Generator for Creating Two-Ways Bridges between C++ Native World and .NET World. Visual Studio 2017 is now supported.

xInterop C++ .NET Bridge 4.0 is available to the public for evaluation to anyone who is interested in using xInterop C++ .NET Bridge to

  • Generating C# .NET Wrapper/Bridge for native C++ DLLs so that you can call native C++ DLL from .NET.
  • Generating C++ Native DLL Bridge for .NET assemblies so that you can call .NET assemblies from native C++.

You may want to download it from the link below and start evaluating it and experiencing how powerful xInterop C++ .NET Bridge is. Once you start using xInterop C++ .NET Bridge, you will find that it is so easy to bridge between the C++ native world to C# .NET managed world by using xInterop C++ .NET Bridge. You will be able to evaluate the software for free for 30 days.

 

To anyone who is interested in purchasing xInterop C++ .NET Bridge, the licensing model and pricing document is available to you upon request. If you have any questions regarding xInterop C++ .NET Bridge software, licensing or pricing, please feel free to contact us using the Contact Us Page.

Ultimate Guide to Call .NET Assembly from Native C/C++ Using Unmanaged Exports

I have been mentioning Unmanaged Exports in a few of my articles, which is a very basic technique allowing us to export managed methods from .NET world to native C and C++. The resulting assembly is a mixed mode DLL containing native-like export entry. You can use Unmanaged Exports Nuget Package to create such DLLs, As long as you can write the native C/C++ declaration of the functions correctly, you should be able to create export function with simple and primitive types. But I went further to write an article named Unmanaged Exports, An Ultimate Guide to Call .NET Assembly from Native C/C++ Using Unmanaged Exports, once you learn those advanced tips, you should be able to even export classes, structs.

xInterop .NET Bridge: Creating a C++ native DLL bridging to C# managed assembly

Creating a C++ native bridge DLL calling into C# classes and methods in a managed assembly using xInterop .NET Bridge

Terminology

Before we start talking about the features of xInterop .NET Bridge can offer, we would like to explain the terminology of such a Bridge. There are different words which may be used to describe such a technology for accessing and calling the C# method from a native C++ application. C++ wrapper, C++ binding, C++ Bridge, you name it. Our bridge technology provides 2 way communication between C++ native world and the .NET managed world. A “Bridge” may better represent our technology and product, it creates wrapper or binding in both directions from C/C++ to .NET and from .NET to C/C++.

Overview

When we started design xInterop .NET Bridge, one of the important requirements is the process of creating the C++ Bridge must be automatic and very use-friendly to users/developers. For any existing .NET assembly, since the information of all classes is already embedded in the assembly as the metadata.

xInterop .NET Bridge is able to retrieve all the class information including methods, properties, fields, etc., analyze the metadata and then create a C++ DLL bridging to the .NET assembly by exporting all the corresponding C++ classes to the .NET classes in the managed world.

Once built, A C++ Bridge DLL automatically loads .NET run-time and the corresponding .NET assembly which it Bridges to. There is no method required to make that happen, it is all handled by xInterop .NET Bridge.

Let’s take an example of how we can create a C++ Bridge DLL allowing developers to call C# assembly from native C++.

Step 1, create a C# .NET library project called CalculatorDemo

The assembly contains a single class named Calculator whose implementation is shown below.

Build the C# project, we will have a CalculatorDemo.dll, a C# .NET assembly. Now let’s feed the .NET assembly to xInterop .NET Bridge.

Step 2, Create xInterop C++ Bridge to C# assembly

Right click on the menu of “Create New C++ Bridge Project…” and bring up the following window for further configuration.

  • .NET assembly

It is the path to the file of .NET assembly which shall be Bridged to the C++ native DLL.

  • Platform Toolset

It is the compiler and also targeting the C++ runtime, depending on the Visual Studio installed on the local machine, the following versions of Visual Studio are supported.

Visual Studio 2013

Visual Studio 2012

Visual Studio 2010

It will be possible to support Visual Studio 2008 and Visual Studio 2005, Since we are building new C++ DLL, developers may prefer to using newer version of Visual Studio compiler. So both of Visual Studio 2008 and 2005 are currently not supported.

  • CPU Architecture

Either x86 or x64 version of the C++ Bridge DLL can be created and built. When AnyCPU is used, both of DLLs shall be created.

  • Unicode

Unicode or ANSI, this defines the character encoding used in the C++ Bridge DLL, it is the same setting of a Visual Studio C++ project.

When using C++ smart pointers, any pointer of an instance will be wrapped in a C++ smart pointer, for capability with SWIG, shared_ptr is used for smart pointer. This is to make sure that any memory allocated when calling the .NET assembly get freed when they are going out of scope.

  • Undefine method name

A name of C# method, property, field may has conflict with existing C++ macro defined, “Undefine method name” can make sure the existing C++ macro undefine before defining the method using the same name.

  • Export interface

Any .NET interface can be Bridged to a C++ native DLL by creating a C++ Bridge class to wrap all the methods of any .NET interface. If such interfaces are not desired, they are not necessarily needed to be Bridged and exported since creating additional C++ Bridge class increases the size of the resulting C++ Bridge DLL.

  • Show build information

When the option is checked and enabled, there will be information printed out in the output window when the building process is going on.

  • Load .NET assembly automatically

The .NET assembly can be loaded by calling xiInitializeBridgeAssembly, it can also be loaded automatically when any of the C++ Bridge class is accessed. When this option is enabled, the .NET assembly must reside in the same directory when the C++ Bridge DLL is located.

  • Create testing application

For the convenience of setting up the C++ application along with the C# Bridge assembly, xInterop .NET Bridge creates a C++ console application(a visual studio solution) for testing when this option is enabled.

  • Number of iteration

There are lots of C# .NET classes referenced in a single .NET assembly directly or indirectly. Creating C++ Bridge classes for all the referenced .NET class is not necessary and it creates a C++ Bridge DLL with huge size. The number of iteration limits the loop which searches for .NET classes referenced by classes, methods, properties and fields. The default is 0 which means directly referenced by the .NET assembly.

  • Depth of base types

The .NET assembly contains classes defined in itself, it may also be derived from .NET classes defined in other assembly, such as the runtime, the depth of base types is to instruct how xInterop should create C++ Bridge class for those base classes. The default is zero, which means no C++ Bridge classes should be created for any of the base class. 1 means only the direct base class shall have a C++ Bridge class.

  • Output directory

This is the root directory where the C++ Bridge DLL project and the testing application project shall be created.

Once the C++ Bridge generating process is done. You should find very pleasant messages printed in the output window as shown below

Basically speaking, xInterop .NET Bridge creates a C# Bridge assembly project which builds a C# Bridge managed assembly. It also creates C++ Bridge native DLL with a header file so that the DLL can be referenced from your native C++ application. The C++ Bridge DLL access the original .NET assembly through the intermediate C# Bridge assembly. The C# Bridge assembly is a C# wrapper for the C++ Bridge DLL with additional features added.

The solution explorer contains the C# .NET Bridge assembly project which is the result of wrapping the C++ Bridge native DLL as shown in the screenshot below.

If you have selected “Create Testing Application”, you should be able simply open the directory where is the solution file is located by double-clicking the link.

Step 3, writing the C++ console testing application

It you open the TestApp.sln solution, there will be 2 projects shown up in the solution folder.

The TestApp is already set as the Startup application, it does not directly reference the C# Bridge assembly project because it can not. It does depend on the C# Bridge assembly project, and it will copy all the necessary DLL and assembly into it is $(Configuration) folder(Debug/Release) so that it can load the DLL/assembly at runtime.

If you open the TestApp.cpp, you will find all the header file and lib file are already included or linked programmatically.

Okay, both the C++ native DLL and the C# Bridge assembly are ready for use, we can now implement the C++ console application by simply adding a few lines.

And let’s look at how the C++ Calculator is defined in the header file of CalculatorDemoBridge.h.

As you can see, the C++ Bridge class of Calculator mimic the exact interface of the corresponding C# Calculator. The C++ Calculator is derived from NObject C++ class which represents the .NET System.Object class.

We have the declaration of the C++ NObject shown below.

You may have noticed that NObject implements all the methods of System.Object class except GetType method which will be implemented in a future version. The method of GetType may be useful when using .NET reflection from the native C++ application.

This is a very simple demonstration showing what xInterop .NET Bridge can offer. It only shows a little bit of the features of xInterop .NET Bridge. The little sample application is able to demonstrate how you can use xInterop .NET Bridge create the C++ Bridge DLL and the C# Bridge assembly.

In the future posts, we will describe more how this works and how you can create C++ Bridge native DLL for calling more complicated .NET assembly.

Introduction to the xInterop .NET bridge

Introduction

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.

http://blogs.msdn.com/b/thottams/archive/2007/06/02/pinvoke-reverse-pinvoke-and-stdcall-cdecl.aspx

http://tigerang.blogspot.com/2008/09/reverse-pinvoke.html

(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.

How is nested class in native C++ handled by xInterop NGen++ ?

How is inner class in C++ wrapped in C# by xInterop NGen++?

In C++, an inner class or nested class is a class declared entirely within the body of another class, nesting class. Inner classes are basically a form of scope. C# supports inner class or nested class as well, so mapping a nested C++ class in a nesting C++ class to a nested C# wrapper class in a nesting C# wrapper class is doable in theory. But how?

The following native C++ code is a very simple example of declaring a nested class inside another class, a nesting C++ class. In the following example, the nested native C++ class is called NestedObject which is declared and implemented inside of the nesting C++ native class named SimpleObject.

xInterop NGen++ (A C# wrapper generator for the native C++ DLL) fully supports nested class, nested struct/structure, nested enum, even nested anonymous struct/structure and nested anonymous enum via pure Explicit P/Invoke. Calling into a native nested C++ class from C# .NET and accessing its method and fields has no difference of calling a regular native C++ class.

We always look into the issues which other code generators such as like SWIG (Simplified Wrapper and Interface Generator) and CXXI are facing while working on implementing and improving xInterop NGen++. CXXI is not very active as of today. SWIG does not really support nested classes or its support is limited from reading its document, but it does provide some workarounds with defining the nested class inside the nesting class where it is forward declared, which means the actual declaration and implementation should be defined outside of the class where the nested class is forward declared in order for SWIG to process it. On SWIG’s to-do-list of 2013 Google Summer of Code, the difficulty is marked as medium to hard. I am not an expert of SWIG implementation or using SWIG to create C# wrapper semi-automatically, but I think its difficulty may have something to do with the fact that SWIG’s underlying mechanism of wrapping C++ is another layer of C style DLL, which means SWIG must wrap the native C++ DLL in a C style DLL which then gets wrapped in C# by using Explicit P/Invoke.

When wrapping the native un-managed native C++ class residing in a native C++ DLL, xInterop NGen++ takes a different approach than SWIG. xInterop NGen++ does not try to wrap the original C++ native un-managed DLL in another C style DLL except that it needs to generate a supplement C++ DLL when any instantiated template class is not exported in the original C++ DLL in order to export the instantiated template class, xInterop NGen++ uses the native C++ DLL as it is. The C# .NET code generated by xInterop NGen++ operates on the pointer of C++ object/instance exactly like a traditional C++ application linking with that native C++ DLL based on the information of the memory layout and the method signatures of a C++ object, including both exported methods and virtual methods. The resulting C# wrapper class has exact same interface of the corresponding native C++ class does, which enables developers to easily convert a C++ application to a C# application when using the native C++ DLL via the generated C# wrapper library.

To xInterop NGen++, any native unmanaged C++ object is basically just a pointer pointing to the beginning of a specific block of memory in the unmanaged native world. The layout, virtual function table and the exported methods of the C++ object are all known to xInterop NGen++. An instance of a nested class is just another native pointer. So it does not matter if the class of the object is nested or not. Basically speaking, being nested or not is just a name scope of the class definition in the original C++ source code.

The way which xInterop NGen++ chose to handle the native nested C++ class is same as the way of handling other regular native C++ classes, a corresponding C# .NET wrapper class gets generated for each native nested C++ class. As for the name scope or namespace, the C# .NET wrapper class of the native nested C++ class will be put inside of the C# .NET wrapper class of the C++ nesting class where the native C++ nested class resides so that the original C++ class structure can be maintained.

I have listed the meta data and class definition of the C# .NET wrapper class of the native C++ nesting class along with nested class below.

If you look into the preceding code carefully, you would find that the structure of the interface of the C# nested inner class has no much difference than a regular top-level C# wrapper class, they are both derived from the same base C# class, the only difference is that the nested inner class is declared and implemented in another C# wrapper class like it does in C++. It is a difference on the name scope in C++ native world, it is also just the same difference on the name scope in the C# managed world, so they are perfectly matched in both worlds.

Wrapping the native C++ class with multiple inheritance in C#

Generating C# wrapper class for the native C++ class with multiple inheritance

xInterop NGen++ fully supports wrapping the native C++ class with multiple inheritance by using C# .NET Explicit P/Invoke.

Let’s talk about the concept of C++ multiple inheritance first briefly. In C++, you can derive a class from any number of base classes. Deriving a class from more than one direct base class is called multiple inheritance.

On the other hand, C# unfortunately only supports deriving from a single base class.

Take a look at the following class diagram for example. The following classes are part of SFML implementation with our version of SFML C# Wrapper libraries as I discussed in the previous blog.

In the preceding example, class Window, RenderTarget are direct base classes for the derived class RenderWindow:

We will be able to wrap each class one-to-one in C# for class RenderWindow, class Window and RenderTarget. While in C#, we won’t be able to do the following like in C++ because C# only supports single inheritance.

The solution we use in xInterop NGen++ is to let class RenderWindow derive from the first class, in this case, class Window and then generate code to implement the public methods of all other classes in a way of interface, more clearly, explicit interface, so the implementation of class RenderWindow in C# shall look like the following,

In the C# wrapper library, IRenderTarget defines all the public methods in the wrapper class of RenderTarget. The reason we chose to implement C# explicit interface instead of C# implicit interface is that we want to guarantee that there is no method with the same name and the same signature in class Window and the interface of IRenderTarget since generating C# wrapper code is an automated process.

This does introduce inconvenience because the method implemented in class RenderWindow via explicit interface is private, you will have to type-cast RenderWindow to IRenderTarget before you can access the methods of IRenderTarget.

Marshaling C++ string, a std::string or std::wstring in C#

Marshaling C++ std::string in C# is possible and doable and it is done

Marshaling C++ std::string in C# is difficult, developers asked questions for help on the web everywhere for many years since .NET was born and PInvoke Interop became a must between C++ and .NET.(C++/CLI uses PInvoke as well, it is implicit P/Invoke, the actual P/Invoke implementation is invisible to the developers, but it still uses P/Invoke), I have a list of questions asked on the web here, they are all different situations, but all they want to do is to able to marshal or access the std::string from C#.

C# Strings in C++

Interface to C++ (unmanaged) DLL and std::string or std::wstring

Pass C# string to C++ and pass C++ result (string, char*.. whatever) to C#

 

All the answers point out that there is no way you can do in C# because the nature of std:string. Is that really true that you really do not have any way to marshal a std::string in C#? It is really a simple object in C++, right?

A std::string in C++, is not a sequence of char like char*, char[], it is an instance of C++ class, which means you will have to access it through the interface of the std::string class. You can not simply marshal a std::string in C++ to string, StringBuilder in C#, it is not going to work, it is just wrong, the .NET run-time will throw out memory access violation exception.

C# Wrapper Library for C++ Run-Time Classes

All that said, it is difficult to create and access a std::string from C#, but the truth is that you can, you can access any instance of C++ class from C# if it can be accessed from C++ code via dynamic linking. That is where the C# Wrapper Library for C++ run-time comes into play, it will make the std::string to C# string marshaling so easy. The C# Wrapper Library implements wrapper classes for most of the run-time standard C++ classes. It is certainly a big helper when automatically generating a C# wrapper for C++ DLL, It is also very useful when you have C DLL involving some standard C++ classes in its interface of C style methods. For any standard classes, such as std::string, std::wstring, std::iostream, std::fstream, you won’t be able to create or access them without such a wrapper library in C#.

A C++ std::string can be created and accessed from C# by using its C# wrapper class, StdString.(Same to std::wstring, it has wrapper class, StdWString)

Metadata of StdString, the C# wrapper class of std::string

I am showing the complete metadata of the C# wrapper class of StdString.

 

C# Wrapper Generator for C++ DLL

The class of StdString was generated by C# Wrapper Generator for C++ DLL automatically, it was pre-generated and put in the C# wrapper library for C++ runtime for convenience, since there won’t be difference between a pre-generated one and the one generated for a custom C++ DLL later, and a Custom C++ DLL mostly won’t have a std::string exported in the DLL anyway.

If you look into the StdString class, you will find all the methods you are familiar in C++. If you have pieces of code you have from C++ to manipulate the strings, you have do the same in C# now, the only thing is it will affect the performance because you will be calling each C++ method through P/Invoke.

Example of marshaling std::string from C#

Let’s write a real C function involving accepting a std::string and returning a std::string.

There are different ways to declare the P/Invoke signature in C#.

You can either marshal std::string to IntPtr or StdString depending on your preference.

Marshal std::string to IntPtr

Marsahl std::string to StdString

You have seen how a std::string can be marshaled from C# to C++ by using StdString from the C# Wrapper Library for C++ DLL. Without such a library, passing or accessing a std::string from C# is just so difficult, P/Invoke do not necessarily mean difficult, with certain tools such as the C# Wrapper Library for C++ DLL.

 

 

 

Creating and Accessing Instantiated std::vector Template Class from .NET

C++ Vectors are sequence containers representing arrays of certain data type, which can change in size. It is widely used by lots of C++ application, if we did not include in our C# wrapper library for C++ DLL, it would be very difficult for the C# wrapper generator to create wrapper classes for C++ class automatically and smoothly since lots of classes may contain interfaces using std::vector of any data type, it is so common that we just would not be able to ignore it. A template class is not a concrete class until it gets instantiated, so a vector template class is really lots of classes with different types contained in that class, in order to map all kinds of vector class of different data type, the C# wrapper library for C++ run-time contains a bunch of wrapper class for each of the instantiated template class, see the list below. All the wrapper classes were generated by the C# wrapper generator with fine tuning specifically done to the vector type of template class.

Not seeing the vector of the data type you want? no worry, the C# wrapper generator has the capability of generating any type of template classes of any types as long as they can be instantiated from C++ using that C++ DLL, for std::vector, you can have std:vector<any_of_your_type>, including your own class and structure. It actually can automatically discover the template class inside the C++ DLL interface, instantiate that type of template class and create the wrapper class for that instantiated C++ template class. It is quite powerful, we will be discussing that in later blogs. For developer’s convenience, we added the pre-instantiated template class in the C# wrapper library for C++ run-time, which makes it useful even when using C DLL.

Since most of the functionality of all of the wrapper classes, the only difference is that each wrapper class contain different type of data type. We will be discussing the wrapper class of std::vector<std::string>, StdStringVector.

std::vector<std::string> is commonly used to pass or retrieve an array of C++ strings, without the help of the C# wrapper library for C++ run-time, it would be very complex for developers to marshal this data type from C++ from C#. Any other kinds of solution targeting marshaling the data type would be time-consuming, or just wasting developers’ valuable time.

Developers asked questions on stackoverflow, I listed a few of them below,

How to Get array of string from Native Code(C++) in Managed Code(C#)

How to marshal collection in c# to pass to native (C++) code

C# pinvoke marshalling structure containg vector<structure>

Without a wrapper class for std::vector<std::string>, such as StdStringVector, there are really no simple answer for those questions, developers would have to do a lot of work to marshal this kind of instantiated template class, besides this, std::string still needs to be marshaled before std::vector<std::string> can be marshaled.

Let’s look into the details of the class of StdStringVector, the .NET wrapper class for std::vector<std::string>. The followings are the metadata I copied and pasted from VS IDE.

StdStringVector wraps all the public methods of the C++ counterpart, std::vector<std::string>, so you can find all the methods familiar in C++ world, like push_back, pop_back, size, etc, to make it easier for developers to use in .NET, the names of all the methods are not kept without change.

How do developers to marshal std::vector<std::string> from C# to C++? let’s take an earlier example of the wrapper class of StdString, we would need to change a little bit of it.

Again, let’s write a P/Invoke for it, remember, every C# wrapper class can be converted to a .NET IntPtr, and they also have a public marshaller class for each of them.

Okay, now we have figured out the way to pass the object from C# to C++ via P/Invoke, let’s talk about the ways to access the data inside of the C++ vector instance.

There are two different ways to access StdStringVector class hence the C++ vector depending how developers would want to. Let’s give an example of how to iterate the vector and print them out to the console.

If developers prefer the way they usually do in C++ as a C++ developer, they can use iterator as they usually do in C++, It also allow them to convert any part of C++ code to C# more easily.

If you look carefully, you would find there are other interfaces and additional methods implemented in the C# version of std::vector<std::string>, those interfaces and methods allow the developer access StdStringVector without using an iterator which is really not a native way to access an array in .NET world. You may have already noticed that it implements IEnumerable interface, ToArray method and string[] type conversion, etc.

Quite simple, right? Developers do not have to do anything else, they would just have the capabilities of manipulating the C++ vector object when using the C# wrapper library for C++ run-time.

A C# .NET Wrapper Library for Standard C++ Classes

In order for our C# wrapper generator for C++ DLL to automatically generate C# source code for C++ DLL, we would have to have a C# wrapper library for the standard C++ run-time library first. Since we were already writing the C# wrapper generator, we used the C# wrapper generator to create the C# wrapper library for the C++ standard run-time classes after some fine-tuning specifically done to the C# wrapper generator for C++ standard classes.

Here are the list of all the C# wrapper classes in the C# wrapper library and the corresponding standard C++ classes.

C++ is one of most widely used programming languages, and std::string is one of the most widely used C++ standard classes. In a C DLL, we use char *, const char* as a string parameter, and in C# you can use string, String, StringBuilder which are automatically marshaled by .NET framework to map the C style string. But, for std::string used in C DLL or C++ DLL, we do not have that luxury any more. The problem is that .NET does not marshal std::string, you simply can not use .NET string to marshal a c++ std::string which is a C++ class instance, it is not just a pointer to a buffer like char*.

Let’s start discussing StdString, the C# wrapper class for C++ std::string.

The following is the metadata of the StdString C# .NET class. It is exactly what I copied from VS studio IDE.

As you can see, the C# wrapper class, StdString has the exact same interface of the corresponding C++ std::string class in .NET, you can use it just like you use it in C++ language, it also provides a Marshaller class which shall allow it to be used as a customer marshaller.

Let’s look at an example of how we can use StdString.

Assuming we have a c style method in a DLL named sample.dll.

Without the C# .NET Wrapper library and the StdString C# wrapper class for the std::string class, we would not able to marshal the std::string in C#, we can not marshal it as string or StringBuilder, both of them won’t work. Now, since we have StdString wrapper class, we will be able to marshal the std::string as StdString as following,

One last thing we would want to be clear at the end of this blog, since the underlying C++ DLL only works with certain version of C++ run-time library, and specifically, Microsoft Visual C++ run-time library, the C# .NET Wrapper library will only with that version of C++ run-time.

Introduction to C# PInvoke Interop SDK for C++ DLL

A C# .NET Managed Wrapper Generator for Wrapping Native C++ DLL Automatically

A tool capable of creating C# .NET managed wrappers for native C++ DLLs instantly

 

xInterop NGen++ 2.0 has been released

We are so excited to announce that we are about to release our C# .NET PInvoke Interop SDK which includes a C# .NET ( PInvoke ) Managed Wrapper Generator for native unmanaged C++ DLLs and a C# .NET Managed library for wrapping native C++ standard classes exported in a C++ native unmanaged DLL via PInvoke. It is in beta-testing right now.

For years, developers have been struggling with being unable to call into native C++ DLL exporting native C++ class from C# .NET easily. To access or call native C++ classes exported in a C++ DLL from C# .NET world, there are a few existing technologies, all of them require developers’ extra effort to write either script or C++ code to create a managed C# .NET wrapper DLL via PInvoke to access or call the original native C++ DLL, and there will be more work when you consider the maintenance, none of them are automatic.

Wrapping C++ classes from C# .NET via PInvoke enables developers to access and call their existing native C++ code base in the C# .NET world without manually changing anything or writing anything extra. The only things this SDK tool requires is the native unmanaged C++ DLL itself and all the header files for that native unmanaged C++ DLL, just like being referenced from a native C++ project, further, it does not even require the corresponding lib file for the native unmanaged C++ DLL as normally being required by a C++ compiler when using the native unmanaged C++ DLL from a native unamanged C++ project. Instead of converting all your C++ code to C# .NET code, using C++ DLL or class from your C# code is the ideal way to avoid huge amount of C++ code and leave whatever code fitting in the native C++ code still in the unmanaged world.

Here are the list of the most important features of our C#/.NET PInvoke Interop SDK.

1. Calling C++ class methods from C# .NET into the native unamanged C++ DLL via PInvoke including all the data type marshaling which is completely automatically handled by the C# .NET PInvoke Interop SDK tool.

2. Instantiating native C++ class instances from C# .NET, the life time of the C++ instances are controlled by the C# .NET code.

3. Invoking or calling all the native C++ class methods implemented in native unmanaged C++ classes from C#/.NET code, including both static and non-static methods, both of the exported methods in the native C++ DLL and any of the virtual methods of the C++ classes.

4. Accessing C++ fields implemented in the native C++ classes from C# .NET managed code, including both static and non-static fields. The types of the native C++ fields exposed in C# .NET managed code includes all the primitive types, all the native C++ classes exported in the nateive C++ DLL, struct types, enum types and the standard native C++ classes and instantiated template classes.

5. Subclassing the native unmanaged C++ classes from C# .NET managed code. All the virtual methods in the C++ classes exported from the native unmanaged C++ DLL can be overridden in C# .NET managed code. An instance of such a C# .NET class can then be passed to native C++ DLL as an object of the native C++ derived class. The native unmanaged C++ DLL does not see any difference between C# .NET managed instance and the instance of the C++ derived class.

6. Supporting AnyCPU. If both x86 32 bits and x64 64 bits native C++ DLL are available, building a AnyCPU C# .NET DLL is supported. Both native unmanaged C++ DLLs can be built into the final C# .NET DLL as embedded resource to support the single C# .NET DLL to be used in both x86 and x64 running mode. If only the x86 or the x64 native unmanaged C++ DLL is available, then a C# .NET DLL targeting either x86 or x64 will be built.

7. Wrapping almost all the standard C++ native unmanaged classes to C# .NET managed classes, such as C++ string (std::string), C++ wide character string (std::wstring), C++ io stream (std::iostream), C++ file stream (std::fstream), etc. Providing such a library will enable developers to instantiate and access the standard C++ classes without doing any other data type marshaling from their C# .NET managed code, which is basically impossible without such as C#/.NET library.

8. Automatically recognizing the standard C++ classes used in any of the native C++ class interface. If the native unmanaged C++ DLL happens to have a method like,

The type of std::string will be automatically mapped to the corresponding C# .NET managed class, StdString or simply string depending on how you want to use the method, and there is no extra code or script to write.

9. Automatically recognizing the standard container classes used in the native unmanaged C++ interface and then export the instantiated template classes from a new supplement native C++ DLL to support the C++ class interface, without adding the support of the instantiated template class, any of such class will not be available to the C# .NET managed world. For example, if you happened to define a method with a parameter type of std::vector<int> in one of your C++ classes and std::vector<int> is not exported, std::vector<int> class will be exported in a supplement native C++ DLL and a corresponding C# .NET managed wrapper class for std::vector<int> will be created to support accessing the std::vector<int>. The SDK tool can actually go further if you happened to have std::vector<Rect> where Rect is a struct of rectangle, it will export std::vector<Rect> from the supplement native C++ DLL, implement C# .NET Managed version of Rect and a C# .NET Managed wrapper class for std::vector<Rect> named StdRectVector. In the case that the new supplement requires to access the native unmanaged C++ DLL, it will build a lib file from the native unmanaged C++ DLL and link itself to the library, It is done all automatically, developers do not need to do anything manually. This is one of the most important and most powerful features of our C# .NET PInvoke Interop SDK.

The SDK Tool will try to find all the types in the C++ interface used in the exported classes in the native unmanaged C++ DLL and create corresponding C# type for them if it is needed. For example, If the SDK Tool discovers that a type of std::vector<int> is used in the native unmanaged C++ class interface, a C# .NET managed class named StdIntVector will be generated, and all the types of std::vector<int>*, std::vector<int>&, return type of std::vector<int> will be marshaled as StdIntVector, further std::vector<int>* * can be possibly marshaled as StdIntVector array.

This great feature releases developers from exporting any native template classes when they design their class interface, they will just need to make sure that their non-template classes do get exported in the native unmanaged C++ DLL.

10. Automatically recognizing any of non-standard container template classes in the native unmanaged C++ DLL interface. As long as the template classes is implemented inside of header files, any instantiated template classes can be exported in a supplement native unmanaged C++ DLL and a corresponding C# .NET managed wrapper class will be generated.

11. Automatically recognizing both struct type definitions and enum type definitions in the native unmanaged C++ DLL and then defining the corresponding struct and enum types in C# .NET. Developers have the choice of keeping the same name or renaming them.

12. Automatically recognizing native unmanged C++ function type definitions and implementing the corresponding delegates in C# .NET managed code. If a type of function defined as following in the native unmanaged C++ DLL,

A C# .NET managed delegate of the following will be defined in the C# .NET managed wrapper DLL.

13. Automatically recognizing std::function<function_signature> which will then be implemented as a C# .NET managed class and can be instantiated by using a corresponding C# .NET managed delegate for that function signature, just like the function type definition.

14. Implementing multiple overrides for the same native unmanaged C++ method. For methods with T* C++ parameter, the SDK’s wrapper generator will implement multiple overrides of the same native unmanaged C++ class method in C# .NET managed code.

A type of T* in the native unmanaged C++ does introduce ambiguity in the .NET world because the real meaning of T* is not really clear from C# .NET without looking into the implementation of native unmanaged C++ class method. A workaround of this issue is to implement multiple overrides of the same native unmanaged C++ class method and let developers to pick one since they know what the C++ class method really does.

For example, if you have the following C++ .NET managed method in one of your native unmanaged C++ class,

The following C# .NET managed methods will be implemented to support the method depending on what the C++ native unmanaged method really does, the wrapper generator does not really know what the method really does though.

Among the 4 C# .NET method overrides, the first one is always correct no matter what native unmanaged c++ method really does, but it is inconvenient to use since the developer will have to manually copy the input data to the buffer from the source data. If what the native unmanaged C++ method really does is to accept a byte buffer with another parameter of the number of bytes in the buffer, then the third override is a perfect match. The toolkit will allow you to generate all the possible overrides of the same C++ method, and the developer just need to pick up the one which best fits the original native unmanaged c++ method.

15. Both of the C++ ANSI and Unicode encoded characters and strings are automatically recognized and the corresponding encoding is used to generate the PInvoke function or method signatures.

16. Limited support of pass-by-value when passing an native unmanaged C++ class instance from C# .NET managed code to native unmanaged C++ DLL.

17. The automatically generated source code of the C# .NET managed wrapper is available. And best of all, the C# .NET managed wrapper code is very much readable and it is just like any C# code Developer manually write. It can be modified easily by developers who know C# .NET PInvoke and data type marshaling.

18. When the C++ source code is changed and a new C++ native unmanaged DLL is generated, all you need to is to rebuild the C# .NET managed wrapper automatically by running the C# .NET PInvoke Interop SDK tool against the new C++ native unmanaged DLL and the modified header files one more time, you are done. You can even automate it from a post-build command. You will be able to call or pinvoke into the C++ native DLL on the new interface you just added via PInvoke.

Our C# .NET PInvoke Interop SDK focuses on native unmanaged C++ DLL instead of both native C and native C++ DLLs since there are existing tools which can wrap a native unmanaged C style DLL automatically without developer’s manual involvement. We will add this feature in the future.

Stay tuned, we will be publishing the first demo application of using the C# .NET PInvoke Interop SDK.

Translate »