C#呼叫C++動態連結庫

Ratirae發表於2018-12-25


本文主要參考網路資源,<<visual c++寶典>>,<<C#入門經典>>

1. 準備工作

1. 用vc做一個靜態連結庫

建立一個靜態連結庫

在這裡插入圖片描述
新增標頭檔案 SampleLib.h

//SampleLib.h
/** \brief n1+n2
 * \param n1 第一個加數
 * \param n2 第二個加數
 * \return 返回整型結果
 */
int addition(int n1, int n2);

新增原始檔 SampleLib.cpp

#include "stdafx.h"
#include "SampleLib.h"
int addition(int n1, int n2)
{
	return (n1 + n2);
}

這時會在工程目錄的Debug資料夾中找到 SampleLib.lib 檔案

2. 用vc呼叫靜態連結庫

新建一個控制檯應用程式,來呼叫上面寫的靜態庫, 注意: 呼叫靜態庫要把上面的 SampleLib.lib放在當恰工程目錄下,我在工程目錄下新建了一個libs資料夾,來專門放函式庫檔案. 同時, 還要把上面生成的標頭檔案SampleLib.h拷貝過來, 並新增到工程當中. 如圖
在這裡插入圖片描述
實現程式碼如下:

#include "stdafx.h"
#include "SampleLib.h"    //呼叫函式庫的標頭檔案
#pragma comment (lib,"libs/SampleLib.lib")    //呼叫函式庫,第二個是.lib檔案放置的相對路徑
int main()
{
	int sum;
	sum = addition(3,2);
	printf("%d\n", sum);
	return 0;
}

輸出結果是 5

3. 生成一個動態連結庫

由於,生成dll檔案時要對匯出函式宣告,而呼叫dll檔案時又要重新對呼叫的函式再宣告一次,因此,用條件編譯的方式,將其一次性寫出來,這樣用的時候就不用重新定義(此處參考了<<visual c++ 寶典>>):
dll的標頭檔案 ShowDlg.h

//宣告匯出函式
#include "StdAfx.h"
#ifndef SHOWDLG_H
#define SHOWDLG_H
extern"C"    //此處代表按c風格編譯,避免c++獨特的編譯方式,是的函式名發生改變
{
#define DLLMODLE_FUNCTIONTYPE __declspec(dllexport)    //匯出函式,宣告dll的匯出函式時,編譯此處
//宣告匯出函式
DLLMODLE_FUNCTIONTYPE int mul(int a, int b);    //宣告匯出函式,兩數相乘
DLLMODLE_FUNCTIONTYPE int div(int a, int b);    //匯出函式,a/b
}
#endif

定義檔案 ShowDlg.cpp

#include "StdAfx.h"
#include "ShowDlg.h"
int mul(int a, int b)
{
	return a*b;
}
int div(int a, int b)
{
	return a/b;
}

編譯成功後會在Debug資料夾中生成一個SampleDll.dll檔案和SampleDll.lib

2. 用vc呼叫動態連結庫

還是用第二部分設計的函式來呼叫dll檔案,把ShowDlg.h拷貝到工程目錄下,把SampleDll.dll檔案和SampleDll.lib拷貝到libs資料夾中
標頭檔案

#include "stdafx.h"
#include "SampleLib.h"    //呼叫函式庫的標頭檔案
#pragma comment (lib,"libs/SampleLib.lib")    //呼叫函式庫,第二個是.lib檔案放置的相對路徑
#include "ShowDlg.h"
#pragma comment (lib,"libs/SampleDll.lib")
extern"C"
{
__declspec(dllimport) int mul(int a, int b);    //宣告匯出函式,兩數相乘
__declspec(dllimport) int div(int a, int b);    //匯出函式,a/b
}
int main()
{
	int sum;
	sum = addition(3,2);
	printf("%d\n", sum);
	sum = mul(3,4);
	printf("%d\n", sum);
	return 0;
}

這樣還不行,因為預設查詢dll檔案的路徑是 C:\Windows\System32,要在projct->setting中進行如下設定
在這裡插入圖片描述
執行結果
在這裡插入圖片描述

3. 用C#呼叫C++動態連結庫

編寫C#的demo,在visual stodio2017中新建一個C#語言的控制檯應用程式

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ccproject1
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("hello world");
            Console.ReadLine();
        }
    }
}

這是一個輸出 hello world 的簡單控制檯應用程式,它的工程啟動目錄是: 工程名\bin\Debug 這個路徑待會要用到
現在新增引入DLL檔案的語句:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
//加入下面的引用,DllImport在該名稱空間內
using System.Runtime.InteropServices;
namespace ccproject1
{
    class Program
    {
        [DllImport("../SampleDll.dll")]    //引入dll檔案,注意:引號內的是檔案路徑
        									 //"SampleDll.dll"   為預設路徑C:\Windows\System32
        									 //"/SampleDll.dll"  這是當前工程的啟動目錄,也就是前文提到的工程名\bin\Debug 
        									 //"../SampleDll.dll" ..代表上一級目錄,也就是dll檔案放在了Debug資料夾下
        									 //路徑可以用"\",不過由於"\"的特殊性,應用兩個如:"..\\SampleDll.dll"
        public extern static int mul(int a1, int b1);    //宣告要呼叫的函式,該函式返回a1*a2的值
        static void Main(string[] args)
        {        
            int c = 0;
            c = mul(3, 4);
            Console.WriteLine(c);
            Console.ReadLine();
        }
    }
}

輸出結果如下
在這裡插入圖片描述

相關文章