C#呼叫C++寫的DLL的簡單示例
首先宣告,本人兩年沒碰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的碼友們。