tags:

views:

2030

answers:

9

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?

A: 

You can wrap the .NET component in a COM component - which is quite easy with the .NET tools - and call it via COM.

QBziZ
A: 

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.

Jason Dagit
A: 

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

rp
Mason Bendixen warns against using ClassInterfaceType.AutoDualhttp://blogs.msdn.com/mbend/archive/2007/04/17/classinterfacetype-none-is-my-recommended-option-over-autodispatch-autodual.aspx
cwick
+5  A: 
[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.

Francis B.
A: 

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.

wizlb
A: 

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.

Hallgrim
+6  A: 

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.

Kevin
If you are a C# developer, learning C++/CLI isn't really all that hard either. This is most definitely the way to go. ++ vote
jolson
It sounds like that would require refactoring of the C# code? Is that the case?
Cenoc
I'm pretty sure you could just use native code where needed and then make it a class library that you could use in any .net application. I could be wrong though
Chris T
A: 

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

cwick
+3  A: 

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).

Rob Walker