1. 程式人生 > >C#呼叫C++寫的DLL的簡單示例

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的碼友們。