1. 程式人生 > >DLL匯出函式名稱改編的解決方法

DLL匯出函式名稱改編的解決方法

1.DLL編譯後匯出函式名稱改編

在編寫一個DLL後,為了能被別的程式呼叫,需要將被使用的函式匯出;

但是一般的編譯器都會將到處函式名稱改編;

例如:在VC中新建一個空的win32 dll工程,然後新增下面的檔案;

  1. //dll1.h
  2. #ifdef DLL_API _declspec(dllexport) 
  3. #else
  4. #define DLL_API _declspec(dllexport)
  5. #endif
  6. DLL_API int add(int a, int b);  
  1. //dll1.cpp
  2. #include "dll1.h"
  3. DLL_API int add(int a, int
     b)  
  4. {  
  5.   return a + b;  
  6. }  

編譯以後,得到dll1.dll與dll1.lib;使用Dumpbin.exe或者是Depends工具檢視發現,

dll1.dll中的到處函式名稱為:[email protected]@[email protected] ;這個新的函式名稱是C++編譯器對add函式的名稱進行了改編,

而且不同的編譯器的改編規則也不一樣,這就導致在通過add函式名對函式進行呼叫時無法找到add函式,

因為此時add的函式名稱已經被改編;

2.限定匯出函式名稱

為了解決C與C++能在不同編譯器之間正常呼叫DLL,所以我們希望DLL在編譯過程中不要對函式名稱進行改編;

我們可以在定義匯出函式時,加上限定符 extern "C"

我們把上面的例子修改下:

  1. //dll1.h
  2. #ifdef DLL_API extern "C" _declspec(dllexport) 
  3. #else
  4. #define DLL_API extern "C" _declspec(dllexport)
  5. #endif
  6. DLL_API int add(int a, int b);  
  1. //dll1.cpp
  2. #include "dll1.h"
  3. DLL_API int add(int a, int b)  
  4. {  
  5.   return a + b;  
  6. }  

我們再次編譯得到dll1.dll,通過工具檢視其到匯出函式發現,此時的add函式的匯出名稱仍然是add;

這樣我們就可以在其他編譯器上直接通過add呼叫該函數了;

3.__stdcall關鍵字將使限定無效

如果我們在第二個的基礎上給函式加上__stdcall關鍵字,匯出函式的名稱將仍然被改編;

如果沒有新增__stdcall關鍵字,那麼函式呼叫約定為C呼叫約定。如果加了__stdcall標準呼叫約定,

就是WINAPI呼叫約定,也就是pascal呼叫約定,這種約定與C呼叫約定不一樣。

  1. //dll1.h
  2. #ifdef DLL_API extern "C" _declspec(dllexport) 
  3. #else
  4. #define DLL_API extern "C" _declspec(dllexport)
  5. #endif
  6. DLL_API int __stdcall add(int a, int b);  
  1. //dll1.cpp
  2. #include "dll1.h"
  3. DLL_API __stdcall int add(int a, int b)  
  4. {  
  5.   return a + b;  
  6. }  

重新編譯,然後通過工具檢視DLL的匯出函式,發現名稱為: [email protected]

也就是說如果函式的呼叫約定發生變化,即使在宣告時使用了 extern "C"限定符,函式名稱仍然會

改編;

C語言與Delphi的呼叫約定是不一樣的,Delphi使用的是pascal呼叫約定,如果我們要用C寫一個DLL供Delphi使用,

那麼在匯出函式時應指定其使用標準的函式呼叫約定,但此時 匯出函式名稱就會被改編;

在這種情況下,我們需要通過一個稱為模組定義檔案(DEF)的方法解決名稱被改編的問題;

在上面例子的基礎上,我們給這個工程新增一個字尾為def的檔案dll1.def;然後新增如下程式碼:

  1. //dll1.def
  2. LIBRARY "dll1"
  3. EXPORTS  
  4. add  

此檔案中LIBRARY指定動態連結庫的內部名稱,該名稱與生成的動態連結庫名稱要匹配;

EXPORTS下面就是要匯出的函式;

如果匯出的函式名稱與原始檔中的函式名稱不一樣可以通過下面的語法指定匯出函式名稱:

entryname = internalname

編譯時,編譯器會按照def中指定的函式名稱匯出函式;

重新編譯,通過工具檢視dll1.dll中的匯出函式為add了;

相關推薦

DLL匯出函式名稱改編解決方法

1.DLL編譯後匯出函式名稱改編 在編寫一個DLL後,為了能被別的程式呼叫,需要將被使用的函式匯出; 但是一般的編譯器都會將到處函式名稱改編; 例如:在VC中新建一個空的win32 dll工程,然後新增下面的檔案; //dll1.h #ifdef DLL_

c++ dll匯出函式返回false值C#卻認為是true的處理方法

轉發網址https://stackoverflow.com/questions/1792581/c-from-c-c-function-in-a-dll-returning-false-but-c-sharp-thinks-its-tr 在C++中宣告匯出函式 bool Foo()

檢視DLL匯出函式方法

VS2010中沒有了Depends工具,如何檢視DLL檔案的匯出介面呢? VS2010的操作方法如下: 1. 開啟命令列視窗CMD 2. 執行vcvarsall.bat VS2010 裡vcvarsall.bat是在右鍵VS開啟檔案位置,D:\M

Dll匯出函式劫持通用方法

問題發現 dll劫持是一種常見的攻擊方法,但是也可以用在不知道程式原始碼的情況下除錯dll的函式。之前在滴水教程的視訊中注意到一個問題,視訊作者演示了一個劫持messagebox函式,列印輸出引數的過程,當時學生提問是否存在一種通用的方法可以劫持所有

小米手機Toast顯示帶應用名稱問題解決方法

近期為了適配劉海屏,向公司申購了一步小米8的手機,然後測試人員那邊測出來一堆適配的問題,其中有一個每一個Toast會顯示app的名稱+顯示的內容,然後網上查找了一下解決方法記錄一下,順便封裝了ToastUtil方便呼叫。 1 package cc.wulian.smarthomev6.suppor

javascript如何獲取函式名稱和引數方法例項詳解

一、獲取函式名稱的3種實現方法   例項1: 在js權威指南中看到的一個方法: 1 2 3 Function.prototype.getName = function(){     return

Dll 匯出函式那些破事

經常使用VC6的Dependency檢視DLL匯出函式的名字,會發現有DLL匯出函式的名字有時大不相同,導致不同的原因大多是和編譯DLL時候指定DLL匯出函式的界定符有關係。 VC++支援兩種語言:即C/C++,這也是造成DLL匯出函式差異的根源 我們用VS2008新建個DLL工程,工程名為

Mysql自定義函式報錯解決方法

1、在MySql中建立自定義函式報錯資訊如下: ERROR 1418 (HY000): This function has none of DETERMINISTIC, NO SQL, or READS SQL DATA in its declaration and binary loggi

問題事件名稱 APPCRASH 解決方法

                問題事件名稱: APPCRASH(解決方法)(轉)  下面分享一下解決win7或者是Vista的一個刺手的問題APPCRASH(app是程式的意思,crash是墜機的意思。就是程式崩潰了/程式撞車……)我們使用軟體的時候有時候會出現這種情況舉個例子Dungeon—fighter

centos 資料夾,檔案 名稱亂碼 解決方法

centos附件打包下載後,解壓,檔案以及資料夾名稱顯示亂碼 解決方法:  1,安裝convmv  [[email protected] chesunexcelfiledevimage]# yum install convmv 2,批量 遞迴 修改當前目錄下的檔名&

關於程式集生成失敗-引用的第三方DLL沒有強名稱解決辦法

          如果一個Assembly希望封裝成為ActiveX/COM元件,那麼它必須擁有強名(Strong Name),也就是說在編譯的時候需要指定SNK(Strong Name Key)。但是當一個Assembly如果以擁有強名的方式編譯的話,它又要求所有自身

python環境配置過程中提示api-ms-win-crt-runtime-l1-1-0.dll丟失的兩種解決方法

一、問題描述win7 64位下api-ms-win-crt-runtime-l1-1-0.dll 丟失提醒二、解決問題api-ms-win-crt-runtime-l1-1-0.dll:下載地址方法:把

VS開發環境下生成和呼叫dll出現的問題和解決方法-1

dll生成和呼叫方法網上很多,省略。  1 build之後只生成了dll檔案,沒有lib檔案。 原因和方法:沒有對任何的類或者函式定義DLL interface,需要對類或者函式定義DLL interface,定義方法如下: 對於類: class _declspec(

VC++  DLL 匯出函式

經常使用VC6的Dependency檢視DLL匯出函式的名字,會發現有DLL匯出函式的名字有時大不相同,導致不同的原因大多是和編譯DLL時候指定DLL匯出函式的界定符有關係。 VC++支援兩種語言:即C/C++,這也是造成DLL匯出函式差異的根源 我們用VS2008新建

api-ms-win-crt**.dll缺失原因分析和解決方法

  系統是否安裝了此類更新,可以通過檢視“系統資訊”來判斷,操作:Win鍵+R,輸入 cmd  /k  systeminfo.exe 確定。當然,也可以通過開啟控制面板或使用第三方工具來檢視。   如果系統中未安裝KB2999226、KB3118401更新,則利用系統Windows Update掃描更新

問題事件名稱: APPCRASH(解決方法)

下面分享一下解決win7或者是Vista的一個刺手的問題 APPCRASH(app是程式的意思,crash是墜機的意思。就是程式崩潰了/程式撞車) 我們使用軟體的時候有時候會出現這種情況 舉個例子 Dungeon&;fighter已停止工作、 問題簽名: 問題事件名稱:A

Fragment帶引數建構函式時報錯解決方法

報錯資訊如下: android.support.v4.app.Fragment$InstantiationException: Unable to instantiate fragment ***.b

VS2010怎麼用Dumpbin來檢視DLL匯出函式

首先,開始->所有程式->Microsoft Visual Studio 2010->Visual Studio Tools ->“Visual Studio 命令提示(2010)” 開啟後輸入 dumpbin -exports D:\C_engin

dll 匯出函式名的那些事

關鍵字: VC++  DLL  匯出函式  經常使用VC6的Dependency檢視DLL匯出函式的名字,會發現有DLL匯出函式的名字有時大不相同,導致不同的原因大多是和編譯DLL時候指定DLL匯出函式的界定符有關係。 VC++支援兩種語言:即C/C++,這也是造成D

import win32api 出現ImportError: DLL load failed 錯誤的解決方法

版本:python 3.6 最近在做scrapy,建立的很順利,開始爬了,就會提示提示import win32api出現錯誤 網上的解決方法大多都是安裝pywin32 import win32api後還是會出錯: import win32api raceb