We are Working on C# Wrapper Generator for Windows .NET Compact Framework

C# Wrapper Generator for Windows .NET Compack Framework

Microsoft will be releasing Windows Embedded Compact 2013, Windows Compact Framework 3.9 will be released at the same time. Wrapping C++ classes in a shared library in C Style methods in another DLL is currently the only way that developers can access the functions of those C+ classes in a C++ DLL, but it is really time-consuming if you look at the picture of wrapping them in C style method. We are working on a prototype of enabling our C# Wrapper Generator to output C# code which are compatible with Windows .NET Compact Framework, there are differences between desktop version of the .NET Framework and the compact version, we are looking into the details. Please stay tuned if you are Windows CE developers.

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 »