2011-12-23 52 views
0

我有一個在VC++中與DLL鏈接的主程序。事實證明,如果我在頭文件DLL之外聲明類方法,所有編譯和鏈接都很好,但Main無法訪問它們。在源文件(VC++)中定義時未導出DLL方法

//mydll.h 
#if XXX_EXPORTS 
#define CLASS_DECLSPEC __declspec(dllexport) 
#else 
#define CLASS_DECLSPEC __declspec(dllimport) 
#endif 


class CLASS_DECLSPEC COrbitPropagator 
{ 
public: 
    int test(double initime, std::vector<double> inivector); 
} 

如果我定義在頭文件(inline或此聲明下文)的主要工作的測試方法。然而,如果我在一個.cpp源文件中定義該方法主調用此方法時,它輸出該消息失敗,並且:

HEAP [MAIN.EXE]:指定RtlFreeHeap無效地址(003A0000, 003C2CE8)

這兩個運行時(DLL和主)都設置爲調試多線程DLL,但我嘗試了其他組合。有沒有解決方法?我想避免在頭文件中寫入所有的DLL代碼!

EDITED: This only happens when the method uses the stl (e.g. std::vector, std::string) 
+0

首先,您可能需要通過引用傳遞'inivector','std :: vector &'。但是在導出的函數中傳遞模板類可能是個不錯的主意。我不會那樣做。 – 2011-12-23 11:30:19

+0

跨模塊邊界傳遞模板類只是要求麻煩;如果它工作,我會更驚訝。 – tenfour 2011-12-23 11:34:21

回答

3

當你在標題中寫的代碼,它的工作原理,因爲該調用內聯,所以它從來就沒有到該DLL搜索它。

您可以使用基本工具:Dependency Walker來檢查測試功能是否已導入/導出。

無論如何,您通過複製將std::vector傳遞給DLL。因此,DLL和EXE使用相同的C++頭文件,庫文件,編譯器版本和編譯器選項進行編譯和鏈接,這正是正好是的必要條件。

如果不遵循這個規則,例如,DLL是調試和EXE是釋放,那麼你會得到非常奇怪的效果:如果你需要混合的DLL隨意損壞,死機等

和EXE編譯方式不同,那麼接口必須受到嚴格限制(C語言沒有交叉動態內存)。

+0

感謝Rodrigo等人。爲您的寶貴答案。通過引用傳遞矢量絕對有效!編譯器選項並不完全相同,因爲VC++強加它(例如,DLL應該有__stdcall,而main應該有__cdecl調用約定)。 – 2011-12-23 13:46:55