Back in May 2005 I posted an article on how to mix C# and C++ code in single assembly.
I still get emails asking for samples. So I created this simple sample. Enjoy.
We have this simple unmanaged C++ class UnmanagedFoo:
E:\sample\vc\mixed>more ufoo.h#include <stdio.h>class UnmanagedFoo{public: UnmanagedFoo() {printf("Constructing UnmanagedFoo\n");} ~UnmanagedFoo() {printf("Destructing UnmanagedFoo\n");} void ShowYourself();};
And implementation:
E:\sample\vc\mixed>more ufoo.cpp#include "ufoo.h"void UnmanagedFoo::ShowYourself(){ printf("UnmanagedFoo\n");}
Another simple C++/CLI class ManagedFoo, with a member of UnmanagedFoo.
E:\sample\vc\mixed>more mfoo.cpp#include "ufoo.h"#using <mscorlib.dll>using namespace System;
ref class ManagedFoo{public: ManagedFoo() { Console::WriteLine("Constructing ManagedFoo"); m_foo = new UnmanagedFoo(); if (!m_foo) { throw gcnew OutOfMemoryException(); } } ~ManagedFoo() {ShowDestruction();} !ManagedFoo() {ShowDestruction();} void ShowYourself() { Console::WriteLine("ManagedFoo"); m_foo->ShowYourself(); }private: void ShowDestruction() { if (m_foo) { delete m_foo; }
Console::WriteLine("Destructing ManagedFoo"); } UnmanagedFoo *m_foo;};
C# class Bar uses ManagedFoo:
E:\sample\vc\mixed>more bar.csusing System;class Bar{ public static void Main() { ManagedFoo foo = new ManagedFoo(); foo.ShowYourself(); }}
Let us build the project.
First, compile ufoo.cpp into (unmanaged) obj file.
E:\sample\vc\mixed>cl.exe /Zi /MD /c ufoo.cppMicrosoft (R) 32-bit C/C++ Optimizing Compiler Version 14.00.50727.42 for 80x86Copyright (C) Microsoft Corporation. All rights reserved.
ufoo.cpp
And mfoo.cpp
E:\sample\vc\mixed>cl.exe /Zi /clr /c mfoo.cppMicrosoft (R) C/C++ Optimizing Compiler Version 14.00.50727.42for Microsoft (R) .NET Framework version 2.00.50727.88Copyright (C) Microsoft Corporation. All rights reserved.
mfoo.cpp
And bar.cs, referencing mfoo.obj
E:\sample\vc\mixed>csc /target:module /addmodule:mfoo.obj bar.csMicrosoft (R) Visual C# 2005 Compiler version 8.00.50727.88for Microsoft (R) Windows (R) 2005 Framework version 2.0.50727Copyright (C) Microsoft Corporation 2001-2005. All rights reserved.
Finally, let’s link everything together.
E:\sample\vc\mixed>link mfoo.obj ufoo.obj bar.netmodule /entry:Bar.Main /out:test.exe /subsystem:console /ltcgMicrosoft (R) Incremental Linker Version 8.00.50727.42Copyright (C) Microsoft Corporation. All rights reserved.
Generating codeFinished generating code
Now we have a single file assembly test.exe, mixed with unmanaged C++, C++/CLI, and C#.
E:\sample\vc\mixed>testConstructing ManagedFooConstructing UnmanagedFooManagedFooUnmanagedFooDestructing UnmanagedFooDestructing ManagedFoo
We can also put ufoo.obj into a lib and link the lib in the final step, instead of using ufoo.obj directly.
E:\sample\vc\mixed>lib ufoo.obj /out:ufoo.libMicrosoft (R) Library Manager Version 8.00.50727.42Copyright (C) Microsoft Corporation. All rights reserved.
E:\sample\vc\mixed>link mfoo.obj ufoo.lib bar.netmodule /entry:Bar.Main /out:test2.exe /subsystem:console /ltcgMicrosoft (R) Incremental Linker Version 8.00.50727.42Copyright (C) Microsoft Corporation. All rights reserved.
E:\sample\vc\mixed>test2Constructing ManagedFooConstructing UnmanagedFooManagedFooUnmanagedFooDestructing UnmanagedFooDestructing ManagedFoo