Suppose I am writing an application in C++ and C#. I want to write the low level parts in C++ and write the high level logic in C#. How can I load a .NET assembly from my C++ program and start calling methods and accessing the properties of my C# classes?
You can wrap the .NET component in a COM component - which is quite easy with the .NET tools - and call it via COM.
If the low level parts in in C++ then typically you call that from the C# code passing in the values that are needed. This should work in the standard way that you're probably accustomed to. You'll need to read up on marshalling for example.
You could look at this blog to get some concrete details.
Create your .NET assembly as normal, but be sure to mark the class with the ClassInterface(ClassInterfaceType.AutoDual) and be sure an assembly info SetAssemblyAtribute to ComVisible( true ).
Then, create the COM wrapper with REGASM:
regasm mydll.dll /tlb:mydll.tbl /codebase f:_code\ClassLibraryForCom
be sure to use the /codebase directive -- it is necessary if you aren't going to give the assembly a strong name.
rp
[Guid("123565C4-C5FA-4512-A560-1D47F9FDFA20")]
public interface IConfig
{
[DispId(1)]
string Destination{ get; }
[DispId(2)]
void Unserialize();
[DispId(3)]
void Serialize();
}
[ComVisible(true)]
[Guid("12AC8095-BD27-4de8-A30B-991940666927")]
[ClassInterface(ClassInterfaceType.None)]
public sealed class Config : IConfig
{
public Config()
{
}
public string Destination
{
get { return ""; }
}
public void Serialize()
{
}
public void Unserialize()
{
}
}
After that, you need to regasm your assembly. Regasm will add the necessary registry entries to allow your .NET component to be see as a COM Component. After, you can call your .NET Component in C++ in the same way as any other COM component.
Since C# can import C++ standard exports, it might be easier to load up your C++ dll inside of a C# application instead of using COM from C++.
See documentation for System.Runtime.InteropServices.DllImport.
Also, here is a complete list of the types of Interop that you can do between managed and unmanaged code:
http://blogs.msdn.com/deeptanshuv/archive/2005/06/26/432870.aspx
In a nutshell:
(a) Using COM-Interop
(b) Using imports/pinvoke (explicit method calls)
(c) IJW and MC++ apps : MC++ & IJW apps can freely call back and forth to each other.
(d) Hosting. This is rare, but the CLR can be hosted by an unmanaged app which means that the runtime invokes a bunch of hosting callbacks.
If you can have both managed and unmanaged code in your process, you can create a C++ class with virtual functions. Implement the class with mixed mode C++/CLI. Inject the implementation to your C++ code, so that the (high-level) implementation can be called from your (low-level) C++ code.
You should really look into C++/CLI. It makes tasks like this nearly trivial.
Otherwise, you'll have to generate COM wrappers around the C# code and have your C++ app call the COM wrappers.
I found this link to embedding Mono: http://www.mono-project.com/Embedding_Mono
It provides what seems to be a pretty straightforward interface for interacting with assemblies. This could be an attractive option, especially if you want to be cross-platform
I would definitely investigate C++/CLI for this and avoid COM and all the registration hassles that tends to produce.
What is the motivation for using C++? If it is simply style then you might find you can write everything in C++/CLI. If it is performance then calling back and forth between managed C++ and unmanaged code is relatively straight forward. But it is never going to be transparent. You can't pass a managed pointer to unmanaged code first without pinning it so that the garbage collector won't move it, and of course unmanaged code won't know about your managed types. But managed (C++) code can know about your unmanaged types.
One other thing to note is that C++/CLI assemblies that include unmanaged code will be architecture specific. You will need separates builds for x86 and x64 (and IA64).