我正在開發一個帶有插件系統的程序,它允許用戶以DLL文件的形式開發自己的模塊。 模塊應該使用在由應用程序的所有組件導入的DLL中定義的對象。下面是一個示例對象將是什麼樣子:導出構造函數的風險造成堆損壞
#include <boost/system/api_config.hpp>
#if defined BOOST_WINDOWS_API
#ifdef EXPORT
#define API __declspec(dllexport)
#else
#define API __declspec(dllimport)
#endif
#else
#define API
#endif
class A
{
public:
API A();
API virtual ~A();
};
所有DLL靜態建(用自己的CRT),並具有完全相同的編譯標誌。我知道通過DLL邊界交換對象可能會變得毛茸茸的,所以我幾乎在任何地方都使用boost::shared_ptr
。圍繞對象構造函數有一個困難:如果我在堆棧上創建對象(來自不同的DLL),則所有事情都按預期工作。但是,如果我使用運算符new
,則會刪除該對象時堆損壞。
A a; // Works fine, no problem when the object goes out of scope.
A* b = new A();
delete b; // Causes heap corruption!
這是什麼方法?如果我必須在對象的DLL中定義一個方法,例如A* A::create() { return new A(); }
,我覺得代碼的可讀性會降低。在最糟糕的情況下,我想讓new
運營商保持私密,以確保用戶不會使用它。
我不知道我得到您的問題。從你展示的內容來看,你的DLL裏沒有任何東西,因爲所有的函數都是「inline」的。你通常不需要在內聯函數或模板上使用'__declspec'。 –
如果我更改代碼,以便構造函數和析構函數不是內聯的,它對我來說很有用。您確定您爲DLL和使用它的代碼都指定了兼容的鏈接器選項嗎? (特別是,你可能需要系統地使用'/ MD'或'/ MDd',沒有它,你會看到這樣的問題。) –
我的構造函數/析構函數實際上不是內聯函數,我編輯了文章以反映它。我確認我得到了堆腐敗。我的構建標誌確實是'/ MT'和'/ MTD',但我不想改變它們。 – executifs