一 方法
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