Fastest way to call C++ code from C#?

I would like to write plug-ins for my application using C#.

My plan was to make the C# objects COM visible and derive from my plug-in interface.

I’ve been told that the transition to and from managed code is a very expensive operation and I should limit the transitions as much as possible. This makes sense but I would still like to do things in the most optimal way since there will be no way from the transitions to be eliminated.

That said, what would be the optimal way to call C# code from C++ (COM) and C++ code from C#

My current plan is to use COM visible interfaces to call C# code C++ and COM connection points to call C++ code from C#.



Answer this question

Fastest way to call C++ code from C#?

  • AlanBirtles

    Hi,

    When you compile with the CLR option your compiler and linker know that you are using the managed libraries, this in conjunction with your mscorelib inclusion allows you to interact with managed objects within your C++ component. If you create an ATL COM with CLR you are creating an unmanaged object that uses some managed components, but is still unmanaged. Your component will create your unmanaged classes on the application memory and your managed objects on the CLR, therefore is a smoth relationship. Of course this mixed code has limitations, for example, you can not have a managed type inside an unmanaged class, but you can solve this using static objects.

    You will have to manually marshall the types, you will have to convert a char* to a System::String (not rocket science but just an example where the marshalling is). This is why the fastest way is to have all your code in C++ exposing your COM interface as a normal managed interface (instead of exposing it as COM). Of course is more work but you have asked for the most efficient way .

    Now, if you create an ATL COM and you consume it as a COM object in C# there is no difference, the wrapper class will be created and no different will be noticeable as you well said.

    In a nutshell:

    1) COM to C# will need a wrapper (no matter if the COM use /CLR)
    2) Most performance way: Use C++ component to expose a normal managed interface (no COM) to C#
    3) If you have to consume a COM it is better to consume it on a C++ component as you manage the marshalling.

    Hope this is clear enough , feel free to ask me if you a part is not clear.

    Cheers



  • clarkcj1

    Thanks SalvaPatuel for the pointers.

    I still have a few questions though.

    First, if I compile my C++ ATL COM server object with /CLR I don’t see how that will improve the performance. I’m new to the interop thing so please forgive me if it should be obvious. Won’t the transition just occur when calls are made to the C++ ATL COM server rather than when calls are made to the C# objects

    Is the transition more efficient at this level for some reason

    Or maybe there is a way to force the C++ ATL COM server to exist as a native object and then explicitly switch to managed code where needed. If so, how do I do this

    I tried simply switching on the /CLR for a C++ COM server object and I could immediately see the marshaling between the calling C++ code and the CLR COM server code. Calls to the C# code were no longer marshaled but that’s because the COM object was CLR.

    Thanks.


  • PitG

    Hi,

    The fastest way to interact with unmanaged code is actually writting everything in C++, where you can mix managed and unmanaged code in a less expensive way as you control the marshalling and has a clear interface to use COM without wrappers.

    (COM from c#) Now, if you want to use COM from your C# application (no matter if it is c++, vb or delphi as the cost is the same) a wrapper will be built that marshalls the IUknown interface and performs the unmanaged conversion to the COM dispatcher. This is the way to interact with COM from c# or vb.net. It is not recommended for high performance applications but it is acceptable for any other purpose.

    (c# from COM) I recommend you to create a C++ COM component with mixed code, this will allow you to interact with a c# dll within your applicaiton using controlled marshalling, therefore you create your C++ ATL COM with the /CLR option in your compiler, this will allow you to reference your C# code).

    Hope this helps



  • AlfonsAberg

    More to ask,< xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />

     

    Since using a managed C++ component to interact interop with C# is the preferred method then I suppose I could just use a C++ DLL with /CLR on. This would actually be simpler for my application to use and would eliminate some of the registration requirements.

     

    I experimented and it seems to work but I still see the native / managed transition occurring where I believe it should not be if I’m understanding this whole thing.  The transition was in the same place when using the ATL COM /CLR solution.

     

    The native program is linking implicitly with the DLL (no LoadLibrary calls).

    Here is my call stack to clarify:

     

    CSharpLib.Class1.DoSomething()     C#

    CInteropDLL::Update(0)                   C++

    [Frames below may be incorrect and/or missing, no symbols loaded for mscorwks.dll]       

    [Native to Managed Transition]         

    wmain(1, 0x00355c90)                       C++

     

    The main program is native, the DLL is C++ with /CLR. It appears that the marshalling is happening between the program and the DLL and I have not specifically marshaled anything. The CInteropDLL class in unmanaged and it has a gcroot pointer to the C# object.

     

    Should I be concerned here or is this not a performance issue


  • Fastest way to call C++ code from C#?