2015-12-18 38 views
0

我正在查看導出函數的文檔,它聲明__declspec(dllexport)應該在命令行版本-EXPORT之前使用,如果可能的話。我目前正在使用命令行變體。在試圖做出這些改變時,我試圖理解正確的實現,但我遇到了問題。使用__declspec(dllexport)而不是-EXPORT:

DLL的頭文件:

#ifdef LIBRARY_EXPORTS 
#define LIBRARY_API __declspec(dllexport) 
#else 
#define LIBRARY_API __declspec(dllimport) 
#endif 

#define PRINT_TEST(name) LIBRARY_API void name() 
typedef PRINT_TEST(print_log); 
//^What's the C++11 equivalent with the using keyword? 

DLL的源文件:

PRINT_TEST(PrintTest) { 
    std::cout << "Testing DLL" << std::endl; 
} 

應用程序的源文件:

print_test* printTest = reinterpret_cast<print_test*>(GetProcAddress(testDLL, "PrintTest")); 

就是因爲__declspec(dllexport)的問題包括在的typedef?因此,應用程序源文件中的聲明實際上是:

__declspec(dllexport) void (*print_test)() printTest = reinterpret_cast<print_test*>(GetProcAddress(testDLL, "PrintTest")); 

我沒有收到任何編譯器錯誤或警告。

+0

我有個問題,爲什麼你要從.dll動態獲取你的函數,而不是包含.dlls頭文件,鏈接到.dlll文件? –

+1

很難猜測LIBRARY_API可能是什麼。使用/ EXPORT鏈接器選項是從DLL導出標識符的一種方法。這是最痛苦的做法。下一個更痛苦的方式是使用.def文件。目前最簡單的方法是在源代碼中應用__declspec(dllexport)屬性。選擇你認爲最簡單的就是更簡單的方法。 –

+0

你有什麼問題? 'GetProcAddress'返回NULL? – 1201ProgramAlarm

回答

2

問題是因爲您正在導出C++函數,該函數具有錯位的名稱。要麼你需要的是錯位的名稱傳遞給GetProcAddress(從來沒有的樂趣),或者你需要在函數聲明

LIBRARY_API __stdcall void PrintTest 

extern "C"使用__stdcall到unmangle出口。 __stdcall更簡單,並將調用約定從C++風格改爲C風格。 (由於C函數名稱的導出方式,這可能需要將「_PrintTest」傳遞給GetProcAddress)。

+0

非常感謝。這個名字是一個問題。我正在看看地圖文件是否包含所有生成的函數簽名?如果函數名稱和參數永遠不變,它保證是一樣的? – Kookehs

+1

@Kookehs糾正兩個問題。在映射文件中列出了重名的名稱,並且除非參數類型或返回類型更改,否則重名的名稱不會更改。 – 1201ProgramAlarm

相關問題