Advanced technology to wrap native C++ template class in C# automatically

XInterop NGen++‘s amazing abilities of wrapping C++ class in C# .NET automatically

The bridge between C++ and C# .NET world is getting much more advanced than ever.

Templates are a feature of the C++ programming language that allow functions and classes to operate with generic types. This allows a function or class to work on many different data types without being rewritten for each one. This is effectively a Turing-complete language. Templates are of great utility to programmers in C++, especially when combined with multiple inheritance and operator overloading. The C++ Standard Library provides many useful functions within a framework of connected templates.

A class template provides a specification for generating classes based on parameters. Class templates are commonly used to implement containers. A class template is instantiated by passing a given set of types to it as template arguments. The C++ Standard Library contains many class templates, in particular the containers adapted from the Standard Template Library, such as std::vector, std::set, set::map.

.NET P/Invoke technology has been around since the beginning of .NET framework. We all know that P/Invoke can be used to call C-style methods in a native DLL from C#. It is a misunderstanding that P/Invoke is only good for C-style DLLs, and popular with people who want to call into the Windows API. The fact is that P/Invoke can also be used to call member methods of a C++ class from C# as well. P/Invoke is designed with the ability of calling any method written in C/C++ in the native un-managed world.

The way we use to call C++ class and method via P/Invoke from C# is really new. When I just started writing xInterop NGen++ (A C# wrapper generator for native C++ DLL), I really did not have this feature in mind and I could not image that I would end up with such a powerful tool with so many great features with which allows me to create C# wrapper class for whatever template class appearing in any of the methods of the native C++ classes. Other C# wrapper generators for C++, such as SWIG or any other C# wrapper generators you could possibly find at the time when I was writing this blog, do not support template class very well, if you use SWIG, you will still have to find the instantiated template classes first by yourself and then write additional script manually to support creating the C# wrapper class, if you do not know SWIG very well, you won’t be able to easily create a C# wrapper library for your native C++ DLL.

In C++, you can use instantiated template class in the C++ class once the template class is defined.

Let me give you an example of how powerful xInterop NGen++ is when dealing with the instantiated template class. Here is a very simple example, assuming we have a SimpleObject containing one method to initialize the data contained in the class.

By exporting the class of SimpleObject, the method of Initialize gets exported in the native C++ DLL with a very long mangled name and an ordinal number. Developers do not have to worry about the mangled name when using xInterop NGen++ since it is handled automatically by the tool.

Looking at the preceding C++ code carefully, you would notice the input parameter of method of Initialize is very complicated, it is a map, the key of the map is std::string while the value of map is vector of vector of string, vector<vector<string>>. The template classes do not get exported automatically, and the compiler(Visual C++ compiler) actually outputs a warning of the classes being used in the interfaces are not exported. Considering there may be many instantiated template classes being used in all different interfaces, just finding the instantiated template class, exporting them and maintaining such a list could be a big effort in a long run.

Normally, you would need to export all the instantiated template classes in the interfaces if you want to use them. But in the case of using xInterop NGen++ to create C# wrapper class for the native C++ class, developers don’t need to do anything with any instantiated template classes, all they need to do is just define the instantiated template class in their interface.

xInterop NGen++ automatically looks into all the methods, fields, it iterates each type of all the parameters, and discovers that all the instantiated template classes which do not get exported already in the original native C++ DLL, and export them in a supplement native c++ DLL which links to the original native C++ DLL.

xInterop NGen++ automatically generates friendly name of the C# wrapper class for the corresponding native instantiated template class.

Let’s take the following example of an instantiated template class,

xInterop NGen++ generates a C# wrapper class of StdStringStdStringVectorVectorMap.

Not only does the C# map class support the interface(methods and fields) of the corresponding native C++ class, it also implements IDictionary interface, so you will be able to manipulate the C# map class just like a C# native dictionary class. With IDictionary interface implemented for the C# wrapper class, developers can even use LINQ to manipulate the C# wrapper class of the C++ native map class.

The template class actually contains several other template classes, corresponding C# wrapper class get generated.

Translate »