您的位置:首页 > 编程语言 > C语言/C++

C#调用C++写的DLL的简单示例

2012-03-17 22:57 691 查看
首先声明,本人两年没碰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的码友们。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: