1. 程式人生 > >C#呼叫C/C++動態連結庫(.dll)詳解

C#呼叫C/C++動態連結庫(.dll)詳解

第一篇編譯C的動態連線庫

在實際工作中,我們經常會將C語言中的.lib.h檔案(靜態庫)編譯成動態連線庫.dll檔案(這裡只提供這兩種檔案,沒有完整的工程),以提供給其他語言平臺呼叫。

1,必須有.lib檔案,只有.h檔案是無法編譯動態連線庫的。

2,我使用的是VS2008,這裡開啟VS,新建專案win32控制檯應用程式,輸入專案名稱,點選確定,圖示如fig.1所示。

                                       C呼叫C/C++動態連結庫(.dll)詳解 - CSharp - C Fig.1

3,點選下一步,依次如圖fig.2-3所示,最後點選完成,就會生成一個帶有.cpp的檔案。

                                       C呼叫C/C++動態連結庫(.dll)詳解 - CSharp - C
                                      C呼叫C/C++動態連結庫(.dll)詳解 - CSharp - C 4,開啟專案屬性配置屬性連結器輸入,如下圖fig.4所示,在附加依賴項中加入你要新增的.lib檔案,如果有一些系統.lib庫沒有新增或出現錯誤,可以在忽略特定庫中新增該庫。

注意:如果編譯的dll檔案呼叫中出現“xx.dll中找不到函式xx的入口點”,很有可能是一個xx.def檔案沒有新增,該檔案的內容是EXPORTS函式名@+序號,xx.def這個名字填寫到下圖介面的“模組定義檔案”,格式為“./xx.def”。如果這個檔案中沒有你要呼叫的API 函式,那麼你在C#中是呼叫不到這個函式的,同時這個檔案你可以通過記事本自己編輯,

注意!!!

                                     C呼叫C/C++動態連結庫(.dll)詳解 - CSharp - C

5,在.cpp檔案中新增.h檔案的引用,不需要把所有的.h檔案都引用進去,只需要.lib檔案入口相關的.h檔案。

6,最後把.lib.h檔案拷貝到工程debug目錄裡,生成解決方案就Ok了,你會發現.dlldebug目錄中出現。

7,最後附上xx.def的格式說明

EXPORTS

[email protected]

[email protected]

[email protected]

。。。。。。。省略了呵呵

第二篇C#呼叫C/C++的動態連線庫

1

,清楚C++C#型別對應關係,即呼叫關係:

                     C呼叫C/C++動態連結庫(.dll)詳解 - CSharp - C

除此之外,

c++:HANDLE(void *) ---- c#:System.IntPtr

c++:WORD(unsigned short) ---- c#:System.UInt16

c++:DWORD(unsigned long) ---- c#:System.UInt32

c++:結構體 ---- c#:public struct 結構體{};

c++:結構體 &變數名 ---- c#:ref 結構體 變數名

c++:結構體 **變數名 ---- c#:out

c++:GUID ---- c#:Guid

c++:UINT8 * ---- c#:ref byte

c++:char*/void*(指向一個字串) ---- c#:string

對於結構體中的指標陣列,對應於C#中的IntPtr[]型別,如:

int * a[] -------------- IntPtr[]a

2,清楚在C#中呼叫C/C++.dll檔案的一般格式

using System.Runtime.InteropServices; //必須引用的名稱空間

[DllImport("user32.dll")]
public static extern ReturnType FunctionName(type arg1,type arg2,...);

//必須定義為類的靜態外部的方法

3[DllImport(引數)]設定

“xx.dll” dll檔名字

CharSet :控制呼叫函式的名稱版本及指示如何向方法封送 String 引數。如果CharSet 欄位設定為 Unicode,則所有字串引數在傳遞到非託管實現之前都轉換成Unicode 字元。這還導致向 DLL EntryPoint 的名稱中追加字母“W”。如果此欄位設定為 Ansi,則字串將轉換成 ANSI 字串,同時向 DLL EntryPoint 的名稱中追加字母“A”

EntryPoint 指示要呼叫的 DLL 入口點的名稱或序號。如果你想使用自己定義的函式名字fucXX,則:”EntryPoint=fucXX”

ExactSpelling:指示是否應修改非託管 DLL 中的入口點的名稱,以與 CharSet欄位中指定的 CharSet 值相對應。如果為 true,則當 DllImportAttribute.CharSet欄位設定為 CharSet  Ansi 值時,向方法名稱中追加字母 A,當DllImportAttribute.CharSet 欄位設定為 CharSet  Unicode 值時,向方法的名稱中追加字母 W。此欄位的預設值是 false

PreserveSig:指示託管方法簽名不應轉換成返回 HRESULT、並且可能有一個對應於返回值的附加 [out, retval] 引數的非託管簽名。

SetLastError:指示被呼叫方在從屬性化方法返回之前將呼叫 Win32 API SetLastError true 指示呼叫方將呼叫 SetLastError,預設為 false

4,具體例項

CAPI函式:

Unsigned long int Fuc (int a,void* b);

C#中定義:

[DllImport("testall.dll", ExactSpelling = false)]

public extern static UInt32 Fuc(int a, IntPtr b);//

C中結構體:

#define M 5

typedef struct __BITMAP{

DWord pPixelArrayFormat;

Long lWidth;

Long lHeight;

Long lBuffer [MPAF_MAX_PLANES];

Byte* pPointer[MPAF_MAX_PLANES];

}BITMAP

C#定義:

[StructLayout(LayoutKind.Sequential)] //此句在C#中重新定義結構體時一定要加上

public struct BITMAP

{

[MarshalAs(UnmanagedType.U4)]

public UInt32 pPixelArrayFormat;

[MarshalAs(UnmanagedType.I4)]

public Int32 lWidth;

[MarshalAs(UnmanagedType.I4)]

public Int32 lHeight;

[MarshalAs(UnmanagedType.ByValArray, SizeConst = 5)]

public Int32[] lBuffer;

[MarshalAs(UnmanagedType.ByValArray, SizeConst = 5)]

public IntPtr[] pPointer;//對於結構體中的指標陣列,一般採用IntPtr陣列

}

對於上面的這個結構體,如果在C/C++中出現了結構體指標,那麼我們應該在C#中使用IntPtr型別變數,然後使用如下方法將指標指向結構體。

定義結構體物件S,則在C#中獲取結構體指標的方法如下:

IntPtr intptr = Marshal.AllocHGlobal(Marshal.SizeOf(S)); 
Marshal.StructureToPtr(S, intptr, false); //
將指標intptr指向結構體

操作之後一定要釋放記憶體——
Marshal.FreeHGlobal(intptr);//
釋放分配的非託管記憶體。

反之也可以由指向結構體的指標變數獲取結構體。Marshal.PtrToStructure();

相關推薦

C#呼叫C/C++動態連結(.dll)

第一篇編譯C的動態連線庫 在實際工作中,我們經常會將C語言中的.lib和.h檔案(靜態庫)編譯成動態連線庫.dll檔案(這裡只提供這兩種檔案,沒有完整的工程),以提供給其他語言平臺呼叫。 1,必須有.lib檔案,只有.h檔案是無法編譯動態連線庫的。 2,我使用的是V

vs2010 C++建立和使用動態連結(dll)

一、用C++建立動態連結庫專案:  1、開啟Microsoft Visual Studio 2010,選擇File->New->Project。  2、在NewProject中選擇Inst

C#呼叫動態連結DLL

1.概述 動態連結庫(Dynamic Linked Library):將寫好的函式存在庫中,以供其他程式開發呼叫,呼叫方式為“動態的”。 Windows為應用程式提供了豐富的函式呼叫,這些函式呼叫都包含在動態連結庫中。其中有3個最重要的DLL,Kerne

c#(winform)環境下使用動態連結dll

  1,什麼是dll檔案? DLL(Dynamic Link Library)檔案為動態連結庫檔案,又稱“應用程式拓展”,是軟體檔案型別。在Windows中,許多應用程式並不是一個完整的可執行檔案,它們被分割成一些相對獨立的動態連結庫,

C++ 根據作業系統版本呼叫不同的動態連結

在操作資料庫時遇到一個問題:win7 sp1上編譯ADO程式,在win7 sp1以下版本不能執行,(Win7系統下需要的動態檔案與XP系統的需要的動態連結庫不一樣。需要根據系統的版本載入動態連結庫。) Win7 系統下: 需要的動態連結庫 #import "MSADO15.DLL" re

LuaLaTeX呼叫外部Lua程式與C語言編寫的動態連結

  在LuaLaTeX編譯方式下,雖然可以直接在tex檔案中編寫Lua程式碼,但會受到LaTeX的影響,編寫中並不是很便利。所以我在實際使用中一般都把Lua程式碼的主體部分放在LaTeX的外部,這樣可以完全按照以往的程式設計習慣去編寫。我以前所在的公司,曾經在機器人運動控制系統中使用過Lua

vs2010 建立和C#使用動態連結(dll)

一、VS 用 C++ 建立動態連結庫 Step 1:建立Win32 Console Application 本例中我們建立一個叫做“Test”的Solution。 Step 2:將Ap

C語言動態連結DLL的載入

靜態連結庫在連結時,編譯器會將 .obj 檔案和 .LIB 檔案組織成一個 .exe 檔案,程式執行時,將全部資料載入到記憶體。 如果程式體積較大,功能較為複雜,那麼載入到記憶體中的時間就會比較長,最直接的一個例子就是雙擊開啟一個軟體,要很久才能看到介面。這是靜態連結庫的一個弊端。 動態連結庫有兩種載入方

MFC/Qt下呼叫caffe原始碼(一)---將caffe原始碼生成動態連結dll

本人研一,最近想將用caffe訓出的模型,通過MFC做出一個介面,扔進一張圖片,點選預測,即可呼叫預測分類函式完成測試,並且通過MessageBox彈出最終分類的資訊。 首先通過查資料總結出兩種方法,第一:直接呼叫編譯好的caffe原始碼;(本次用到的原始碼是classif

Java通過JNI 呼叫動態連結DLL

JNI(Java Native Interface)Java本地介面,主要作用是實現java程式碼與C、C++編寫的程式碼互動。 在Android程式設計中,so庫的訪問也用到了jni技術。 理論多說無益,還是看java連線dll的實戰吧。如下: 例:java中呼叫demo.

codeblocks中建立和呼叫動態連結(dll)

一、建立C語言動態連結庫 1.建立。 File->New->Projects->Dynamic Link library->Go 給專案命名為:Dynamic librar

VC中使用動態連結DLL:靜態呼叫動態呼叫

VC中生成DLL的辦法見:www.codeproject.com/KB/DLL/RegDLL.aspx VC中使用DLLhttp://www.cnblogs.com/c1230v/articles/1401448.html 呼叫DLL有兩種方法:靜態呼叫和動態呼叫. (一

【深度學習之Caffe】將模型測試Classification過程生成動態連結dll以方便其他專案呼叫

#include "caffe_classify.h"   #include "head.h"   Classifier::Classifier(const string& model_file,const string& trained_file,const string& mean

Tensorflow安裝在windows 上面出現ImportError: DLL load failed: 動態連結(DLL)初始化例程失敗。

      最近開始學習tensorflow,電腦是win10 64位系統的,已經安裝了python3.6.1 32位的,tensorflow只支援python64位的,所以直接安裝了Python64位3.6.1。直接使用pip install tenso

使用LabVIEW通過動態連結DLL遠端操作Oracle資料庫

很多情況下,遠端操作資料庫時,需要在不裝Oracle客戶端的情況下進行,儘可能降低客戶端安裝各類軟體的時間。 首先我們從網上下載Oracle資料庫操作dll檔案。 動態連結庫通過ildasm.exe反彙編檢視,這個檔案是.net 4.0版本的封裝檔案。 在LabVI

MFC/Qt下呼叫caffe原始碼(二)---MFC下呼叫caffe的動態連線dll檔案

首先,先看下最後的效果吧。 win7 vs2013 新建一個MFC 工程 注:MFC中如何最簡便的方法將圖片顯示到對話方塊中?大家可以搜下,很多種方法,但是我採用的是最簡單的方法,即將opencv視窗繫結到MFC的PIcture control上。 在:

Windows動態連結DLL的使用

windows程式設計使用動態連結庫可以有效的分隔大型專案的模組,DLL裡面主要提供函式的呼叫介面(函式名)供其他的外部引用程式呼叫,呼叫者在完全不知道動態連結庫中的實現方式的情況下,仍然能根據其提供的函式名,函式型別, 和函式的引數實現呼叫。windows程式中建立DLL

動態連結 —— Dll 基礎

1. DLL 的初識   在 windows 中,動態連結庫是不可缺少的一部分,windows 應用程式程式介面提供的所有函式都包含在 DLL 中,其中有三個非常重要的系統 DLL 檔案,分別為 Kernel32.dll、User32.dll 和 GDI32.dll,下面說下這三個重要的 DLL 的用途:

動態連結dll的 靜態載入 與 動態載入

dll 兩種連結方式  : 動態連結和靜態連結(連結亦稱載入) 動態連結是指在生成可執行檔案時不將所有程式用到的函式連結到一個檔案,因為有許多函式在作業系統帶的dll檔案中,當程式執行時直接從作業系統中找。   而 靜態連結就是把所有用到的函式全部連結到exe檔案中。 動態連結是隻建立一個引用的介

VC6.0學習(三)呼叫MatLab 生成動態連結

本人想在win10作業系統下通過VC6.0引用MATLAB生成的dll檔案,這個過程遇到了很多的坑,這裡總結一下具體的過程。 MATLAB生成.dll 這個過程主要可以在網上參考一些文章關於“ VC三種方法用C++呼叫Matlab”。方法沒有問題,關鍵問題出在了C++ sdk的問