亚欧色一区w666天堂,色情一区二区三区免费看,少妇特黄A片一区二区三区,亚洲人成网站999久久久综合,国产av熟女一区二区三区

  • 發布文章
  • 消息中心
點贊
收藏
評論
分享
原創

DLL 導出符號的兩種方式

2023-07-20 07:33:54
23
0

最近恰好需要用 C++ 實現一個供 C# .NET 調用的模塊,用dllexport導出符號的時候出現了一點問題,明明已經看到了導出符號,但是 .NET 在調用的時候,就是找不到方法。然后用 def 文件的方式導出符號就正常,突然對這兩種方式的區別產生興趣,之前一直沒有研究過,就仔細了查閱一番。

以導出名為 TESTFUNC 方法為例:

def 文件方式

,正常在程序中定義方法,然后新建一個 .def 文件,內容類似

LIBRARY
EXPORT
    TESTFUNC

在其他工程使用這個方法的時候需要頭文件,然后在連接時指定 .def 文件目錄。

dllexport方式

在定義 TESTFUNC 方法時,在聲明前加上 __declspec(dllexport)

區別

這里就不得不說導出符號在 DLL 中的形式。實際上對于 C++ 來說,當導出的時候,不會以原名導出,因為會加上一些符號字母后綴,實際上如果了解 C++ 的人,也會知道 C++ 在處理函數重載的時候,其實也用了這個套路,實際上編譯之后就沒有重載的概念了,而是根據參數生成了獨一無二的方法名。

那說回來既然名字不同,那為什么其他模塊調用還沒問題呢。回答這個問題之前要先知道其他模塊如何引用。

調用導出函數的方式

一般有三種形式:

  • .h 提供聲明之后,直接調用,在連接的時候指定 .def 文件目錄;
  • .h 提供聲明之后,直接調用,鏈接的時候指定 .lib 文件地址
  • 內部聲明要調用函數的函數指針,loadlibrary 之后,直接取到函數地址,調用函數;

了解了這三種方式之后,就可以回答上邊的問題。

  • 對于1、2兩種方式,由編譯器自動轉換函數名,尋找到正確的地址,鏈接之;
  • 對于第3種方式,如果不把真正的函數方法名寫對,就找不到函數了。

所以其他模塊調用沒問題。

話說回來,那也不可能每次都把@那些符號寫對。所以會看到有時候導出的時候_extern "C" _declspec(dllexport)這樣寫,這是為了讓函數以 C 的方式來編譯,這樣導出的方法就是沒有那些符號的了,但這樣有個問題,就是函數必須以 C 方式調用,而且也不能用來導出類對象,原因是顯而易見的……

其實當了解上邊之后,不難發現,1、2才是我們最想要的,3就很局限。這樣問題就來了,1、2兩種方式又有什么區別呢:

區別就在這個 .lib 上,如果在 C++ 或者 C 工程這個范圍來說,確實沒區別。但是假如調用工程不是 C++ 工程呢,他就是個 C# 工程呢,他是沒辦法用 .lib 的。

綜上所述:.def 文件的方式才是最通用的做法。那回到我最初的問題,我的 C# 工程之所以在調用使用 dllexport導出的方法失敗,就是因為,我沒有寫對真正的方法名(帶一堆符號的那個)。而使用 .def 文件的話,就沒有這個問題了。

0條評論
0 / 1000
Harper
20文章數
0粉絲數
Harper
20 文章 | 0 粉絲
原創

DLL 導出符號的兩種方式

2023-07-20 07:33:54
23
0

最近恰好需要用 C++ 實現一個供 C# .NET 調用的模塊,用dllexport導出符號的時候出現了一點問題,明明已經看到了導出符號,但是 .NET 在調用的時候,就是找不到方法。然后用 def 文件的方式導出符號就正常,突然對這兩種方式的區別產生興趣,之前一直沒有研究過,就仔細了查閱一番。

以導出名為 TESTFUNC 方法為例:

def 文件方式

,正常在程序中定義方法,然后新建一個 .def 文件,內容類似

LIBRARY
EXPORT
    TESTFUNC

在其他工程使用這個方法的時候需要頭文件,然后在連接時指定 .def 文件目錄。

dllexport方式

在定義 TESTFUNC 方法時,在聲明前加上 __declspec(dllexport)

區別

這里就不得不說導出符號在 DLL 中的形式。實際上對于 C++ 來說,當導出的時候,不會以原名導出,因為會加上一些符號字母后綴,實際上如果了解 C++ 的人,也會知道 C++ 在處理函數重載的時候,其實也用了這個套路,實際上編譯之后就沒有重載的概念了,而是根據參數生成了獨一無二的方法名。

那說回來既然名字不同,那為什么其他模塊調用還沒問題呢。回答這個問題之前要先知道其他模塊如何引用。

調用導出函數的方式

一般有三種形式:

  • .h 提供聲明之后,直接調用,在連接的時候指定 .def 文件目錄;
  • .h 提供聲明之后,直接調用,鏈接的時候指定 .lib 文件地址
  • 內部聲明要調用函數的函數指針,loadlibrary 之后,直接取到函數地址,調用函數;

了解了這三種方式之后,就可以回答上邊的問題。

  • 對于1、2兩種方式,由編譯器自動轉換函數名,尋找到正確的地址,鏈接之;
  • 對于第3種方式,如果不把真正的函數方法名寫對,就找不到函數了。

所以其他模塊調用沒問題。

話說回來,那也不可能每次都把@那些符號寫對。所以會看到有時候導出的時候_extern "C" _declspec(dllexport)這樣寫,這是為了讓函數以 C 的方式來編譯,這樣導出的方法就是沒有那些符號的了,但這樣有個問題,就是函數必須以 C 方式調用,而且也不能用來導出類對象,原因是顯而易見的……

其實當了解上邊之后,不難發現,1、2才是我們最想要的,3就很局限。這樣問題就來了,1、2兩種方式又有什么區別呢:

區別就在這個 .lib 上,如果在 C++ 或者 C 工程這個范圍來說,確實沒區別。但是假如調用工程不是 C++ 工程呢,他就是個 C# 工程呢,他是沒辦法用 .lib 的。

綜上所述:.def 文件的方式才是最通用的做法。那回到我最初的問題,我的 C# 工程之所以在調用使用 dllexport導出的方法失敗,就是因為,我沒有寫對真正的方法名(帶一堆符號的那個)。而使用 .def 文件的話,就沒有這個問題了。

文章來自個人專欄
文章 | 訂閱
0條評論
0 / 1000
請輸入你的評論
0
0