日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

通过GetProcAddress函数动态调用dll中地函数,是否必须通过extern C声明导出函数?(转)...

發布時間:2025/3/19 编程问答 21 豆豆
生活随笔 收集整理的這篇文章主要介紹了 通过GetProcAddress函数动态调用dll中地函数,是否必须通过extern C声明导出函数?(转)... 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
通過GetProcAddress函數動態調用dll中的函數,是否必須通過extern "C"聲明導出函數? [已結貼,結貼人:darongtou]

?

如題,網上搜了N多資料,一直找不到確定的答案,目前我的答案是“”。?晚上因為一個程序,好好研究了一下。?很多資料上都只是說明“如果沒有 extern "C" 修飾,輸出函數僅僅能從 C++ 代碼中調用。”?卻并沒有明確這個調用是通過顯式調用還是隱式調用,我也一直沒有看到過有代碼是通過顯示調用沒有 extern "C" 修飾的導出函數。?MSDN上也只是說?The ? spelling ? and ? case ? of ? the ? function ? name ? pointed ? to ? by ? lpProcName ? must ? be ? identical ? to ? that ? in ? the ? EXPORTS ? statement ? of ? the ? source ? DLL's ? module-definition ? (.DEF) ? file. ? The ? exported ? names ? of ? Win32 ? API ? functions ? may ? differ ? from ? the ? names ? you ? use ? when ? calling ? these ? functions ? in ? your ? code. ??下面再從理論方面進行一些分析:?GetProcAddress函數聲明是:?FARPROC ? GetProcAddress(?? ? HMODULE ? hModule, ? ? ? ? // ? handle ? to ? DLL ? module?? ? LPCSTR ? lpProcName ? ? ? // ? name ? of ? function?);?

?

C++是支持函數重載的,也就是說允許多個不同的函數可以有同樣的函數名,如果不通過extern "C"修飾,就可以輸出相同的函數名。?這樣,就和GetProcAddress函數聲明不一致了,所以推斷不能動態調用沒有extern "C"修飾的導出函數,因為GetProcAddress函數是通過函數名來唯一確定被調用函數的地址的。??歡迎大家討論!

?

第1個回答

顯示調用必須使用extern "C"修飾符。隱式調用可以使用任何類型,但只有C++能調用沒有extern "C"修飾的導出函數。?GetProcAddress是一種通用的獲取函數入口點的API,能被任何語言調用,所以限制一定比較多,比如它的參數一定是一個ANSI串(操作系統并未提供UNICODE版本)。

?

第2個回答我的理解是這樣的:GetProcAddress實際上跟你直接調用myfunc()一樣,都是查詢Export表來得到函數地址再去調用,因此你修飾符不對就會造成找不到entry,是不行的。當然我沒試過,沒有完全的把握。

?

第3個回答C函數和C++函數的名稱是不一樣的,可以使用工具來查看,比如Dependency ? Walker。如果你想試驗,可以根據工具看到的名稱來調用GetProcAddress試試

?

第4個回答主要是就是名字的問題?有兩種例外情況可以不加extern "C":?1。如果不是用C++編譯器而是用C編譯DLL,名字不會變,可以不加extern "C"?2。如果DLL的使用者知道是用C++編譯器編譯DLL,不加extern "C"也可以,因為他知道名字改變的規則。調用GetProcAddress,把函數名字改了就是了

第5個回答

C++編譯器和C編譯器編譯后生成的函數名不一樣。?GetProcAddress認為是cdecl的函數,而?編譯DLL的是VC++,所以要加一個extern "C"的修飾符?指明以cdecl的方式生成函數。

?

第6個回答發現不用加extern "C"也是可以的,只要在調用端用修飾過的函數名即可,不能用原函數名。?

?

例子關鍵代碼如下:?----------------------------?DLL部分:?// ? This ? is ? an ? example ? of ? an ? exported ? function.?DLL1_API ? int ? __cdecl ? fnDll1(void)?{?return ? 42;?}?輸出的修飾函數名為?fnDll1@@YAHXZ?DLL1_API ? int ? __cdecl ? fnDll1(int ? a)?{?return ? 42+a;?}?輸出的修飾函數名為?fnDll1@@YAHH@Z?-----------------------------?EXE部分:?HINSTANCE ? hModule ? = ? LoadLibrary("dll1.dll");?ASSERT(hModule);?typedef ? int ? (*fnDll1)();?fnDll1 ? pfnDll1 ? = ? NULL;?//VERIFY(pfnDll1 ? = ? (fnDll1)::GetProcAddress(hModule, ? "fnDll1"));?VERIFY(pfnDll1 ? = ? (fnDll1)::GetProcAddress(hModule, ? "?fnDll1@@YAHXZ"));?ASSERT(pfnDll1() ? == ? 42);?typedef ? int ? (*fnDll2)(int);?fnDll2 ? pfnDll2 ? = ? NULL;?VERIFY(pfnDll2 ? = ? (fnDll2)::GetProcAddress(hModule, ? "?fnDll1@@YAHH@Z"));?ASSERT(pfnDll2(3) ? == ? 45);?---------------------------?這事暫時可以告一段落了,實驗還是最有力的證明。

?

轉載于:https://www.cnblogs.com/whiteyun/archive/2011/07/22/2113560.html

總結

以上是生活随笔為你收集整理的通过GetProcAddress函数动态调用dll中地函数,是否必须通过extern C声明导出函数?(转)...的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。