I already had to do this, and I used a slightly different approach (I tested this procedure in Visual Studio 2012 and 2013).
For the test, I created a DLL in C#, called Bibliotecacsharp.dll, with the following class and namespace:
using System;
using System.Collections.Generic;
using System.Text;
namespace BibliotecaCSharp
{
public class Teste
{
public int Soma(int a, int b)
{
return a + b;
}
}
}
Now, on the C++ side, on another project, to run a code from a library in . Net (be C#, VB etc), the C++ project must be configured to support CLR, as shown in the figure:
Once the project is configured, it is necessary to import the necessary libraries, which is done inside the file stdafx.h
of your project in C++, simply add these lines to it:
//Includes e bibliotecas específicas do runtime para .Net
#include <mscoree.h>
#include <vcclr.h>
#pragma comment(lib, "mscoree.lib")
From now on, it is possible to instantiate classes written in C#, or VB.Net directly from within the C code++.
This example project in C++ is a simple console application with only one cpp file, but serves to demonstrate the technique:
#include "stdafx.h"
//Em todos os arquivos que forem acessar a classe, deve-se
//importar as bibliotecas e namespaces
#using <mscorlib.dll>
#using "<CAMINHO DA DLL EM C#>\BibliotecaCSharp.dll"
using namespace System;
using namespace BibliotecaCSharp;
int SomaCSharp(int a, int b)
{
//Cria uma instância da classe desejada
Teste^ t = gcnew Teste();
return t->Soma(a, b);
}
int _tmain(int argc, _TCHAR* argv[])
{
int s = SomaCSharp(1, 2);
_tprintf(TEXT("Soma em C#: %d\n"), s);
return 0;
}
However, the way it is, the C++ code will give error during execution, because the #using "<CAMINHO DA DLL EM C#>\BibliotecaCSharp.dll"
is only for the compiler to locate the library, and nay for the program to locate the library when running.
To this end, I always copy the dll in C# to the same folder as the C++ executable, as shown in the figure below:
It would be possible to copy to another folder as long as it is in PATH system, but I find the solution of using the same folder simpler.
Just out of curiosity, this copy can be automated through Post-build Event command line, as the figure shows:
IS necessary create the class with
gcnew
in this case? Or it would work without problems with the class created in the stack?– Guilherme Bernal
Yes, one should use the
gcnew
, whenever the instantiated class is Managed. This way the object that goes to the Managed heap, where the Garbage Collector can act. If you use onlynew
, the object would go to the normal heap of the system, and the Garbage Collector would not be able to monitor it. To avoid this, the compiler no longer even allows the compilation of a code with the buildnew Classe()
, whereClasse
is a Managed class.– carlosrafaelgn