一 方法
C#的project调用C++的DLL,一般也有3中方法:
1)最简单的方法,通过PInvoke,但是只能调用全局function,不能调用Class。
2)通过COM封装调用。
3)通过CLI作为中介,也即本文章所讲的。
二 实例
1)假如我们有的Math的dll,
class CPPDLL_API Math


{
public:
static double Add(double x, double y);
static double Multiply(double x, double y);
};

class CPPDLL_API AdvancedMath


{
public:
static int Factorial(int x);
};

double Math::Add(double x, double y)


{
return x + y;
}
double Math::Multiply(double x, double y)


{
return x * y;
}
int AdvancedMath::Factorial(int x)


{
if(x <= 0)
return 0;
if(1 == x)
return 1;
return x * Factorial(x - 1);
}
2)C++的MFC的Dialog调用(比较烦,特别是MFC的controls太少了。各种String间的转化也和累啊,我这里为了简化,不得不把vs05中默认的unicode改为非unicode)
#pragma comment(lib,"../debug/cppdll.lib")
#include "../cppdll/cppdll.h"

void CCppTestDlg::OnBnClickedButton1()


{
switch(m_op)

{
case Add:

{
CString xStr;
m_EditX.GetWindowText(xStr);
CString yStr;
m_EditY.GetWindowText(yStr);

double x = atof(xStr);
double y = atof(yStr);
double sum =Math::Add(x, y);

CString sumStr;
sumStr.Format("%f",sum);
m_EditSum.SetWindowText(sumStr);
break;
}
case Multiply:

{
CString xStr;
m_EditX.GetWindowText(xStr);
CString yStr;
m_EditY.GetWindowText(yStr);

double x = atof(xStr.GetBuffer());
double y = atof(yStr);
double sum = Math::Multiply(x, y);

CString sumStr;
sumStr.Format("%f",sum);
m_EditSum.SetWindowText(sumStr);
break;
}
case Factorial:

{
CString xStr;
m_EditX.GetWindowText(xStr);

double x = atoi(xStr);
double sum = AdvancedMath::Factorial(x);

CString sumStr;
sumStr.Format("%f",sum);
m_EditSum.SetWindowText(sumStr);
break;
}
default:
break;
}
}
3)CLI的wrapper
#pragma once

class Math;
class AdvancedMath;

namespace CppMathLib


{
public ref class MathWrapper


{
public:
static double Add(double x, double y);
static double Multiply(double x, double y);
};

public ref class AdvancedMathWrapper


{
public:
static int Factorial(int x);
};
}


#include "stdafx.h"
#include "MathWrapper.h"
#pragma comment(lib, "../debug/CppDLL.lib")
#include "../CppDLL/cppdll.h"

using namespace CppMathLib;

double MathWrapper::Add(double x, double y)


{
return Math::Add(x, y);
}
double MathWrapper::Multiply(double x, double y)


{
return Math::Multiply(x,y);
}

int AdvancedMathWrapper::Factorial(int x)


{
return AdvancedMath::Factorial(x);
}
4)C#的Form调用CLI的wrapper
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

namespace CsharpTest


{
enum Operation

{
Add,
Multiply,
Factorial,
None
}
public partial class Form1 : Form

{
private Operation op = Operation.None;

public Form1()

{
InitializeComponent();
}

private void radioButtonMultiply_CheckedChanged(object sender, EventArgs e)

{
op = Operation.Multiply;

textBoxY.Enabled = true;
}

private void radioButtonAdd_CheckedChanged(object sender, EventArgs e)

{
op = Operation.Add;

textBoxY.Enabled = true;
}

private void radioButtonFactorial_CheckedChanged(object sender, EventArgs e)

{
op = Operation.Factorial;

textBoxY.Text = "0";
textBoxY.Enabled = false;
}

private void button1_Click(object sender, EventArgs e)

{
switch(op)

{
case Operation.Add:
textBoxSum.Text = CppMathLib.MathWrapper.Add(Double.Parse(textBoxX.Text), Double.Parse(textBoxY.Text)).ToString();
break;
case Operation.Multiply:
textBoxSum.Text = CppMathLib.MathWrapper.Multiply(Double.Parse(textBoxX.Text), Double.Parse(textBoxY.Text)).ToString();
break;
case Operation.Factorial:
textBoxSum.Text = CppMathLib.AdvancedMathWrapper.Factorial(Int32.Parse(textBoxX.Text)).ToString();
break;
default:
break;
}


}

private void button2_Click(object sender, EventArgs e)

{
this.Close();
}
}
}
三 截图比较


前面的是C++的MFC的dialog,后面的C#的Form,看起来一样哦,就是开发速度不同!
四 代码下载:
http://www.cppblog.com/Files/mzty/CsharpCallCppByCLI.rar