C#/Using C++ class in C# program
Expert: Nick - 2/24/2008
QuestionHi,
I need to write a program that connects to a third party’s server. I got from the third party a C++ API (h file, classes, etc.) and C++ dll that implement that connection and exposes their functionality. The program that I need to write is in C#.
My question is: how do I use C++ dll in a C# program. I’m quite new at C#.
I made a lot of research for that subject, but all that I could find were very complicated solutions that included managed c++ wrappers and then dll import to C#.
I find these solutions a bit too complicated, and before going to that hard work I prefer to check if there is a simpler solution.
If these complicated solutions are the only ones that are available, I would appreciate if you could point me to a clear and comprehensible tutorial, since I couldn’t find such.
What also bothered me in what I found is that these solutions exposed functions from that C++, and I couldn’t see a way to keep a living object (which holds the state of the connection to server and other parameter).
Thanks in advance,
Itzik Turkel
AnswerI feel your pain on this one. Usually, I just opt for libraries which are managed. Although I've never imported a complex unmanaged library, this seems like it should help you (not a tutorial per se, but should be equally effective):
http://www.gamedev.net/community/forums/topic.asp?topic_id=395225
It seems somebody else has gone through the same exact situation as you. Read everything at that link and you should be all set. Unfortunately, it describes the complicated solution, which you have indicated you do not prefer. If you are not interested in that solution, I believe I have devised a similar but possibly easier solution, which I will describe below.
As it turns out, C++ is the only managed language which allows you to mix both managed and unmanaged code. Given that, it would be to your advantage to create your wrappers in managed C++. The reason for this is that if you create the wrappers in managed C++, you may then add a reference to your mangaged C++ DLL and you will completely avoid having to do "DLLImport". I haven't actually tested if that's true, but since you have the server library, I'll leave that for you to test. I created some sample projects to test importing a managed C++ project into a C# project. First, I created a new "Visual C++ CLR Class Library" (CLR = Common Language Runtime, the thing that makes C# and C++ managed). Then I put the following text in the primary file of that project:
// ManagedCPPDLL_Test.h
#pragma once
using namespace System;
namespace ManagedCPPDLL_Test {
public ref class Class1
{
public:
int Multiply(int x, int y)
{
return x * y;
}
};
}
Next, I created a new "Visual C# Windows Application". I created a label on the form called "label1".
The code behind the form consisted of the following text:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
namespace WindowsApplication1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
ManagedCPPDLL_Test.Class1 test = new ManagedCPPDLL_Test.Class1();
label1.Text = test.Multiply(2, 4).ToString();
}
}
}
In order for that to work, you have to add a reference to the DLL that was created from building the managed C++ project. As you can see, my C# code creates an instance of the managed C++ class and calls a method in that instance. Supposing the "Multiply" method required a parameter of an unmanaged type called "ImaginaryNumber", you would have to code a managed version of that class in your managed C++ project as well (the managed ImaginaryNumber would simply create an instance of the unmanaged ImaginaryNumber and create methods that call the methods in the instance of the unmanaged ImaginaryNumber). The good thing about this is that you only have to create managed versions of classes and methods you will actually use... if you don't use a particular method in "ImaginaryNumber", you don't have to create a managed version of it.
By the way, the link I pasted above mentions another useful link:
http://www.swig.org/
As one of the posters mentioned, "You might want to take a look at SWIG as it will interpret your C++/C code and create a C# wrapper for it."
Hope that helps. Let me know if you have any further questions.
-Nick