首先声明,本人两年没碰C++了。只是现在突然要用到,而且是要用C#来调用C++写的DLL,着实让我头疼,在网上摸索了两天,终于找到了适合我的方式。这里我们不管他什么库啊,什么原理了,能用起来就ok了。
也就是说,本文适合的是和我一样之前没有用过C#来调用C++写的dll的新手。
我用的工具是VS2011(非本人情愿,我更愿意用08或10)。
首先我们新建一个DLL工程。这个过程,我当时就摸索了一段时间,VS里面可以建的类型实在是太多了。
File->New project->Visual C++ ->Win32 Console Application
project的名字CreateDLL吧,solution name就写个DLLTest,反正是摸索嘛。
接下来的一步关键了,我们要设置一下这个工程。
相信你已经看到了配置的地方了,DLL,Exports symbols。对了就这两个地方了。
接下来你看到的应该就是这样子的了吧。
你要关心的两个文件,我已经圈出来了,他们是CreateDLL.h与CreateDLL.cpp,相信你改猜到他们是干什么的了,一个声明,一个实现。
下面我们来看一下CreateDLL.cpp中的内容:
// CreateDLL.cpp : Defines the exported functions for the DLL application.
//
#include "stdafx.h"
#include "CreateDLL.h"
// This is an example of an exported variable
CREATEDLL_API int nCreateDLL=0;
// This is an example of an exported function.
CREATEDLL_API int fnCreateDLL(void)
{
return 42;
}
// This is the constructor of a class that has been exported.
// see CreateDLL.h for the class definition
CCreateDLL::CCreateDLL()
{
return;
}
简单说一下各部分,这也是我从别人那里学来的
CREATEDLL_API int nCreateDLL=0;是你想要从dll传给外面用的变量,你可以模仿它去写你自己想传的值;
CREATEDLL_API int fnCreateDLL(void)是供外面使用的函数,你可以模仿它写你自己的函数,待会儿的示例,我会写一个函数的示例。
CCreateDLL::CCreateDLL()这个感觉好高端,传类给外面用了,我反正是没用上,哈哈,你要是要用,你可以研究啦,不过要记得分享一下,让我也学习一下。
头文件CreateDLL.h我也贴一下吧,不过目前没什么好说的。也就是对上面的声明。
#ifdef CREATEDLL_EXPORTS
#define CREATEDLL_API __declspec(dllexport)
#else
#define CREATEDLL_API __declspec(dllimport)
#endif
// This class is exported from the CreateDLL.dll
class CREATEDLL_API CCreateDLL {
public:
CCreateDLL(void);
// TODO: add your methods here.
};
extern CREATEDLL_API int nCreateDLL;
CREATEDLL_API int fnCreateDLL(void);
接下来我就演示一下在dll函数中写一个函数,再在C#中去调用这个函数。
首先我们在CreateDLL.h中添加一个函数声明
extern CREATEDLL_API_API int _stdcallmaxNumber(int x, int y);
这一句和CREATEDLL_API int fnCreateDLL(void);有区别,为什么呢?这是因为调用是有传参数的原因,所以多了一个_stdcall ,你如果也传参数,这个要记得加上,这是我血的教训啊。
声明好了,我们再在CreateDLL.cpp中去实现这个函数:
CREATEDLL_API int _stdcall maxNumber(int x, int y)
{
if(x>y)
return x;
return y;
}
函数很简单就是返回x,y中比较大的一个。大家肯定都懂的。那么接下来就可以用了吗?没有!
我们还少一样东西,那就是.def文件,你问我它什么用,我也说不清,没研究过,我只能说,这个文件写了之后,在外面才能认识你要传的函数。我们这就去加一个吧
我们看一下里面有什么:
就一个单词 LIBRARY ,哈哈,我们要写些什么呢?
写成下面这个样子:
LIBRARY "CreateDLL"
EXPORTS
maxNumber
“CreateDLL”是我们家里生成dll的文件名,maxNumber是我们外面要用到的那个函数。
就这些了,那么你现在可以编译了Build->Build CreateDLL
看到了吗,我们的dll出炉了,新鲜的哦,哈哈。
检验他的时刻到了,我们建一个C#工程,我们就一个Forms类型的工程吧。
右击这个Solution,加一个新工程吧,我建的是Windows Forms Application,名字叫UseDLL
我们打算怎么用这个DLL呢,我添加一个Button按钮,点击按钮后,会用MessageBox,将这个值显示出来
这里可能需要你稍微了解一下Button触发事件了,这个很简单,你肯定能搞定的,如果不会,那你留言,我再把这部分补充好。
看我就是简单的加一个按钮而已,接下来就是双击这个按钮,去按钮触发的地方写个MessageBox显示我们调用DLL后的返回值。
贴一下Form1.cs写之前的代码,这样便于之后进行对比。
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace UseDLL
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
}
}
}
好了,接着我要去写了。贴上写好的Form1.cs
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Runtime.InteropServices;
namespace UseDLL
{
public partial class Form1 : Form
{
[DllImport("CreateDLL.dll")]
public static extern int maxNumber(int x, int y);
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
try
{
int result = maxNumber(1, 2);
MessageBox.Show(result + "");
}
catch
{
}
}
}
}
和上面一对比你就知道哪些是我添加的。
这样运行起来的效果如下:
看见那个激动人心的2了吗,哈哈!
接下来我要给你说一下你可能遇到的错误
1.你可能看到这样一个错误。这个错是因为solution这时候只允许你运行CreateDLL这个project。
这个错误的解决方法是,右击你的solution->properties设置成下面这个样子:
2.这个是关于一个Exception的问题,也就是程序找不到这个Dll文件调用。
应该会遇到的,呵呵。你把你的CreateDLL.dll文件拷贝到 C:\Windows\System32路径下也就能解决这个问题了,
当然其他肯定还有方法,我还没有去试,毕竟工作紧,不得空去多想。也算是弊端吧。
到此为止,我已经写完了,有不足的地方请大家多指教!希望能帮助到想我这样从没用过DLL的码友们。