简体   繁体   中英

Native C++ and C# interop

So I'm architecting an application that does necessarily C++ work, but MFC/ATL is too messy for my liking, so I had this brilliant idea of doing all the "thinking" code in native C++ and all the pretty UI code in C#. The problem, though, is interoperability between the two of them. Before I get too carried away with this, I was wondering if this is a solved problem, and there's a really good way to do this. Note that I don't want to mix logic and display in the same module, as it gives rise to annoyingly high coupling.

Here's what I have so far:

在此输入图像描述

So tell me, can it be done better?

The easiest way to handle this is to use C++/CLI, and expose your logic as .NET types.

It's very easy to wrap a native C++ class in a ref class that's usuable directly from a C# user interface.

That being said - this was my plan, originally, in my current project. My thinking was that I'd need the native code for some of the heavy math work we typically do. I've found, however, that it's been easier, faster, and nicer to just move most of my logic directly into C# (separated from the UI code, but still in a C# assembly) rather than try to implement it in C++.

My experience has been that speed has not been an issue - unsafe C# code has nearly always managed to be as fast or faster than the equivelent C++ when tuned, and it's easier to profile and tune the C# code.

You may have a good reason for your core to be a DLL. But it isn't necessary. I've had success with an application that is C++, it creates an App Domain and loads an assembly into it, then instantiates an object in the app domain and calls it, passing it an interface to the application. This is basically what the C-runtime does when you make an unmanaged app anyway.

The interface that the C++ code exposes to the C# code is defined in C#. I think this is easier than defining the intefaces in pure COM. C# interop gives you more control of the marshalling than C++ does.

  • create a file app_interface.cs that defines the interface
  • compile app_interface.cs into a dll, we don't care about the dll. we need the type library.
  • in the C++ code #import <app_interface.tlb> raw_interfaces_only this turns the typelib into a C++ .h file with interface definitions: app_interface.tlh
  • Implement the interfaces

You can sprinkle your app_interface.cs with attributes that control the marshalling like this

[ComVisible(true)]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
[Guid("ffffffff-ffff-ffff-ffff-ffffffffffff")] // guid changed from what I really use 
public interface IMyHostApplication
{
   ...

   void   AddErrorDetails (
      [MarshalAs(UnmanagedType.Error)] uint hr, 
      [MarshalAs(UnmanagedType.LPWStr)] string  szErrDetails);

   ...
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM