首先聲明,本人兩年沒碰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的碼友們。