How to call C ++ / CLI from C #?

I have a class implemented in C ++ that is responsible for arithmetic computing a program and an interface using WPF. I handle input using C #, but then how can I use my C ++ class?

I saw a few comments on how to create a C ++ wrapper managed class to interact with it, but I don't know where to start. I also don’t know how I am going to compile it with all the other code. I can't find a tutorial on this, and google testimonials in managed C ++ don't really seem useful.

Anything out there to help me? This does not seem unreasonable to me.

EDIT The m3rLinEz solution was fixed, but it gave me a BadImageFormatException exception, I think this is because the DLL is not being generated. I did everything I said, I don’t know what happened. Any ideas?

+62
c ++ c # pinvoke c ++ - cli managed-c ++
Feb 06 '10 at 3:15
source share
4 answers

Do you look at C ++ / CLI?

Let me give you a very short example. Here is the source file from the Visual C ++ project -> CLR -> Class Library. It basically gets the Windows username and returns it.

Please note that in order to compile this file, you need to go to the project settings and mark “Additional Dependencies” as “Inherit from Parent”, because we use these Windows libraries (kernel32.lib, user32.lib, ..)

// CSCPP.h #pragma once #include "windows.h" using namespace System; namespace CSCPP { public ref class Class1 { // TODO: Add your methods for this class here. public: String^ GetText(){ WCHAR acUserName[100]; DWORD nUserName = sizeof(acUserName); if (GetUserName(acUserName, &nUserName)) { String^ name = gcnew String(acUserName); return String::Format("Hello {0} !", name); }else{ return gcnew String("Error!"); } } }; } 

Now create a new C # project and add a link to our first C ++ / CLI class library project. Then call the instance method.

 namespace CSTester { class Program { static void Main(string[] args) { CSCPP.Class1 instance = new CSCPP.Class1(); Console.WriteLine(instance.GetText()); } } } 

This gave the following result on my machine:

Hi m3rlinez!

C ++ / CLI is basically a managed extension according to the C ++ standard. It allows you to use CLR classes and data types in your C ++ / CLI project, and also show this in a managed language. You can create a managed shell for your old C ++ library using this. There are some weird syntaxes like String^ to determine the type of reference for a CLR String. I will find "Quick C ++ / CLI - Learn C ++ / CLI in Less Than 10 Minutes" to be useful here.

+55
Feb 06 2018-10-06T00
source share

There are at least three ways to call unmanaged code from managed code in the same process:

  • C ++ / CLI
  • Platform challenge
  • Wrap your C ++ in a COM object

At work, we use C ++ / CLI for this, it works.

+8
Feb 06 '10 at 9:16
source share

I would create a standard (non-COM / managed) dynamic link library as described here , and then use the DllImport (call the platform) attribute in C # code to access the exported functions.

The key point from this article:

Note the __declspec (dllexport) modifier in the method declarations in this code. These modifiers allow the method that the DLL will export to be used by other applications. For more information, see dllexport, dllimport.

This is an easier alternative to the real shell of COM interoperability and avoids problems such as registration, etc. (DLLs can simply be placed in the application directory).

Another alternative is It Just Works (IJW). This is probably the best choice if you are managing C ++ code and need to access it from other .NET languages. But this is only an option if you can / are happy to convert your unmanaged C ++ to managed C ++, though.

+4
06 Feb '10 at 3:24
source share

I would stay away from P / Invoke as it is rather slow compared to IJW (It Just Works). The latter allows you to easily bind managed and unmanaged C ++. All you have to do is create a managed C ++ assembly, write a managed class visible from C #, and call the unmanaged code from that.

Umm ... Good. I got the impression that P / Invoke calls are slower than they are inherited. However, with explicit sort control, you can make your C ++ / CLI version more efficient in many cases.

Here is a Microsoft article about all the mechanisms:

http://msdn.microsoft.com/en-us/library/ms235282.aspx

IJW Benefits

  • There is no need to write DLLImport attribute declarations for the unmanaged APIs used by the program. Just include the header file and link from the import library.
  • The IJW mechanism is slightly faster (for example, IJW stubs do not work; you need to check the need for connections or copy data, because this is done explicitly by the developer).
  • This clearly illustrates performance issues. In this case, the fact that you are translating from a Unicode string to an ANSI string and that you have appropriate memory allocation and freeing. In this case, a developer writing code using IJW would understand that calling _putws and using PtrToStringChars would be better for performance.
  • If you call many unmanaged APIs using the same data, once and sending a marshaled copy is much more efficient than re-marshaling every time.

There are also aesthetic advantages:

  • C # code looks like C # code without any weird oddities.
  • You do not need to define the DLLImport attribute, you do not need to define any data structure (also using p / invoke specific attributes), which might look like this:

    [StructLayout (LayoutKind.Sequential, CharSet = CharSet.Ansi)] public struct DevMode {[MarshalAs (UnmanagedType.ByValTStr, SizeConst = 32)] public string dmDeviceName; }

  • You do not need to convert all parameter primitives to your .NET copies (there is a table on this page that lists how managed map types are for unmanaged types).
  • You can work with C ++ / CLI, which is very interesting to learn and really polished. It has come a long way since VS 2003 and is now a fully featured .NET language. The Microsoft documentation for this is pretty good, as is all the IJW information.
  • Performing C ++ interactions in C ++ / CLI seems very natural, unlike C #. This is completely subjective, but I would prefer to do string sorting in C ++ that do Marshal.PtrToString(ptr) .
  • If you expose the API, you probably want to wrap all P / Invoke stuff at a different level, so you don't have to deal with P / Invoke ugliness. This way you have the overhead of all marshalling and the C # layer around it. With C ++ / CLI, marshalling and interop abstraction are in one place and you can choose how much marshalling you need.

IMHO, if you call an odd function in the Windows SDK, go to P / Invoke. If you exposed a moderately complex C ++ API to a managed world, specifically the C ++ / CLI.

+3
Feb 06 '10 at 3:30
source share



All Articles