[英]Can't access variable in C++ DLL from a C app
我堅持修復傳統的Visual C ++ 6應用程序。 在我放的C ++ DLL源代碼中
extern "C" _declspec(dllexport) char* MyNewVariable = 0;
這導致MyNewVariable在導出表中顯示(很好地未修飾)(如dumpbin / exports blah.dll所示)。 但是,我無法弄清楚如何聲明變量,以便我可以在C源文件中訪問它。 我嘗試過各種各樣的東西,包括
_declspec(dllimport) char* MyNewVariable;
但這只是給我一個鏈接器錯誤:
未解析的外部符號“__declspec(dllimport)char * MyNewVariable”(__ imp_?MyNewVariable @@ 3PADA)
extern "C" _declspec(dllimport) char* MyNewVariable;
正如Tony所建議的(以及我之前嘗試過的)會產生不同的預期裝飾,但仍然沒有將其刪除:
未解析的外部符號__imp__MyNewVariable
如何編寫聲明,以便可以從C應用程序訪問C ++ DLL變量?
由botismarius和其他人確認(非常感謝所有),我需要鏈接DLL的.lib。 為了防止名稱被破壞,我需要聲明它(在C源代碼中)沒有裝飾器,這意味着我需要使用.lib文件。
你必須鏈接編譯DLL后生成的lib。 在項目的鏈接器選項中,必須添加.lib
文件。 是的,你還應該將變量聲明為:
extern "C" { declspec(dllimport) char MyNewVariable; }
extern“C”是你如何刪除裝飾 - 它應該工作使用:
extern“C”declspec(dllimport)char MyNewVariable;
或者如果你想要一個可以被C ++或C使用的頭文件(帶/ TC開關)
#ifdef __cplusplus
extern "C" {
#endif
declspec(dllimport) char MyNewVariable;
#ifdef __cplusplus
}
#endif
當然,還要與執行導出的dll生成的導入庫鏈接。
我不確定是誰修改了botismarius,因為他是對的。 原因是.lib生成的是導入庫,可以很容易地使用__declspec(dllimport)
簡單地聲明外部變量/函數並使用它。 導入庫只是自動執行必要的LoadLibrary()
和GetProcAddress()
調用。 沒有它,您需要手動調用它們。
他們都是對的。 錯誤消息描述__imp_?MyNewVariable@@3PADA
意味着它正在尋找裝飾名稱,因此extern“C”是必要的。 但是,鏈接到導入庫也是必要的,否則您將獲得不同的鏈接錯誤。
@Graeme:你也是對的。 我認為OP使用的“C”編譯器不是強制執行C99標准,而是編譯為C ++,因此會破壞名稱。 真正的C編譯器不會理解extern "C"
關鍵字的“C”部分。
在dll源代碼中,您應該具有此實現,以便.lib文件導出符號:
extern "C" _declspec(dllexport) char* MyNewVariable = 0;
c客戶端應該使用帶有此聲明的標頭 ,以便客戶端代碼將導入符號:
extern "C" _declspec(dllimport) char* MyNewVariable;
如果dll源代碼中包含#include-ed,則此標頭將導致編譯錯誤,因此通常將其放在導出標頭中,該標頭僅用於導出的函數且僅由客戶端使用。
如果需要,您還可以創建一個“通用”標題,可以包含在以下任何位置:
#ifdef __cplusplus
extern "C" {
#endif
#ifdef dll_source_file
#define EXPORTED declspec(dllexport)
#else
#define EXPORTED declspec(dllimport)
#endif dll_source_file
#ifdef __cplusplus
}
#endif
EXPORTED char* MyNewVariable;
那么dll源代碼如下所示:
#define dll_source_code
#include "universal_header.h"
EXPORTED char* MyNewVariable = 0;
客戶端看起來像這樣:
#include "universal_header.h"
...
MyNewVariable = "Hello, world";
如果你這么做了,頂部的怪物#ifdef可以進入export_magic.h並且universal_header.h變成:
#include "export_magic.h"
EXPORTED char *MyNewVariable;
我在Windows編程時從未使用_declspec(dllimport)。 你應該能夠簡單地宣布
extern "C" char* MyNewVariable;
並鏈接到編譯DLL時創建的.libb。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.