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.

12 thoughts on “Introduction to C# PInvoke Interop SDK for C++ DLL

  1. Nice product. We have a lot of C++ dlls we would want to use in .NET, some of them are very complicated, is it possible to generate C# wrapper dlls for them using your SDK tool?

    • Hi, Thanks for being interested in our C#/.NET PInvoke Interop SDK tool. we have been converting a lot of C++ DLLs in beta testing with success, even unexported template class such as std::map can be supported, the requirement is that you can do the same from C++ when calling them, it has to be callable from outside of the DLL. So, it should be able to.

  2. Sounds Terrific , Can you let me know how to obtain the SDK?

    • We are still beta-testing it right now, it will be ready for public in the next few months. We will be ready to publish a few C# wrapper for open source native DLL for free in the near future before we publicly release our flagship SDK tools, just to show that how much you can achieve with just explicit P/Invoke with C++ DLL.

      If you are willing to join our beta-testing program for free, please let us know, You are welcome and we would be happy to work with you. You may want to use the contact us page to contact us.

      Beta-testing is free of charge while C# PInvoke Interop SDK for C++ DLL tool is a commercial product and we will only release it to the customer who purchased license from us. Any library released during the beta testing is only for testing only, it is not licensed to be used in production, a valid license should be purchased before using the library in production.

  3. This is a very interesting approach to wrapping C++, especially since it’s entirely done through P/Invokes. I’m curious: how do you deal with constructor methods? Do you actually compute the memory layout of each native class, allocate a native IntPtr with that and then call the method?

    If this is all P/Invoke based, does it mean I can use xinterop wrappers with Mono seamlessly, or do you have to regenerate the wrapper because of different C++ name mangling from different compilers?

    Very nice idea, this is an important interop problem that was never satisfactorily solved in the .NET world, imho.

    • Hi, Goncalo,

      Thanks for your comments.

      The C++ Constructor method(s) must be exported in the C++ DLL, otherwise it can not be used in a native application. The generated C# class replies on the native C++ constructor to instantiate an instance and initialize it.

      Yes, you are right, the C# PInvoke Interop SDK for C++ DLL computes the memory layout of the native class and creates the entire class in C# based on the layout information and the exported class methods.

      The C# PInvoke Interop SDK for C++ DLL currently does not support Mono yet, but we are working on it right now. As for mangled name, we only use the mangled name in the C# wrapper generator itself, the generated C# wrapper uses ordinal instead of mangled name, I believe Mono supports ordinal as well. As for the Linux-based compilers, it should be easy for us to find all the information we are able to retrieve from the windows C++ dll compiled by Visual C++ compiler since they are open-sourced.

      I like your last comment very much. It is true. People spent lots of time on writing wrapper manually simply because there is no tool available for them to generate a C# .NET Wrapper for C++ DLL automatically, developers had to re-write their class interfaces using C++/CLI, even for a string conversion, it is just waste of time.

  4. Shawn,

    We would be very interested in beta testing this feature; we really can’t wait for the release. We have a rather complicated C++ implementation that needs to be accessed from C#. We have a functioning C++/CLI version but not PInvoke. In the end this needs to be done on Windows CE. I was hoping that PInvoke would, in itself, work on CE 7 but from some of the comments you have made it appears this may not be the case.

    • Hi, Brian,

      Thanks for your comments and your interest of beta-testing. A follow-up email will be sent to you later to show how we may proceed with the beta-testing.

      Beta-testing is free of charge, C# PInvoke Interop SDK for C++ DLL tool is a commercial product and we will only release it to the customer who purchased license from us. Any library released during the beta testing is only for testing only, it is not licensed to be used in production, a valid license should be purchased before using the library in production.

      Regarding CE 7, there are some limits on P/Invoke of Windows CE platform, but it is still doable since the C# PInvoke Interop SDK for C++ DLL tool can generate most of the marshaling code as long as the basic data types are supported.

  5. How does one invoke this tool? I have been looking at SWIG which seems to do almost everything (as far as I can tell) but it is not that easy to use and the files it generates are difficult to read. So far I have been unable to get SWIG to work as it doesn’t seem to be able to parse my first include file (it fails on included includes).

    • It comes with NGenerator, the C# .NET Wrapper Generator for native C++ DLL. You would simply need to tell it where your DLL file and the header files are. It will then generate the C# wrapper DLL automatically without your involvement. The source code it generates looks like exactly what we usually write, which is indeed what we wrote, it even has comments all over the source code for better understanding.

      Thanks for bringing up SWIG, which is script based, it is free and open source, you do need to spend lots of time on it to make it work, you will need to write scripts and type mappings, support is an issue as well, I guess you already know how difficult to use it.

      Our SDK tool is a commercial product and the tool itself is close-sourced, it is completely automated and maintenance free, no need to write any script, the automation capability is amazing. There is only place you will need to decide what kind of C# interface for the C++ function when there is ambiguousness of the C++ function declaration, such as int *(It will be marshaled as int[] by default which is correct most of the time), the tool does not know it is really just a pointer to a integer variable or a pointer of an integer array. We have added a data type marshaling designer in NGenerator so that you can simply tell it which case it exactly is, it will then generate the wrapper source code.

      I have written a blog showing a few screen shots of NGenerator.

      NGenerator, the C# .NET Wrapper Generator for native C++ DLL

  6. Hello – this tool looks to be what I’ve been searching for, for the last few weeks. I have a large C++ dll that has hundreds of C++ structs and callback functions in the interface.

    I have looked at SWIG but it cannot cope with multiple inheritance and nested structs.

    How can I get involved in beta testing this new option?

    • C# PInvoke Interop SDK for C++ DLL(xInterop NGen++) does support multiple inheritance(inheriting from multiple base classes) by using interfaces because C# itself does not support multiple inheritances. If the class is derived from two classes or more at the same level, the second class will be implemented as interface to support the methods of the original C++ methods.

      Nested structure and union are also supported, both of them get converted to C# structure.

      Structs and callbacks are handled automatically, even std::function is supported.

      C# PInvoke Interop SDK for C++ DLL(xInterop NGen++) is a very much advanced automation tool, it will make your C# wrapper code generated by this tool maintenance free, you can write your C++ library in one instance of Visual Studio and then start using the corresponding C# wrapper in the other C# project in seconds. It is a great bridging tool integrating both C++ and C# together seamlessly.

      C# PInvoke Interop SDK for C++ DLL(xInterop NGen++) is a commerial product, we only release it to the customer who paid for it in the future when it is officially release. If you would like to do beta testing, you can send us the native c++ DLL and all the header files along with a C++ testing application. (Please use the contact us page to contact us) we will then build the C# wrapper library and send it back to you for testing.

      Regarding license, any library released during the beta testing is only for testing only, it is not licensed to be used in production, a valid license should be purchased before using the library in production.