我讀過幾次,傳遞STL對象,如向量和字符串在DLL邊界之外是不好的做法,因爲不同的編譯器版本可以爲STL對象生成不同的代碼。因此,你應該設計一個C風格的接口,而不是傳遞STL對象。然而,還有一些事情我不清楚:正確定義DLL接口與C++ 11/14
1.什麼是DLL的「邊界」?
是否正確地說,邊界是代碼在哪裏編譯在DLL端編譯爲?如果我在一個DLL中定義一個.h文件(編寫一個工廠類)並在不同的項目中使用該頭文件,該怎麼辦?那個.h文件是在DLL的邊界之內還是之外,爲什麼?
2.什麼是包含在DLL中?
讓我們說我有一個類Foo:
class Foo
{
public:
__declspec(dllexport) void f1(); //instantiates v1 inside function
private:
unique_ptr<vector<int>> v1 = nullptr;
}
如果我只標註函數f1()與__declspec(dllexport)的,只有這個功能應該被包含在DLL。如果v1不包含在DLL中,f1()中的代碼如何知道v1是什麼?
3.使用的unique_ptr
我使用的unique_ptr幾乎每次在我的項目傳遞出一個DLL邊界的對象。據我所知,從DLL返回unique_ptr將是不好的做法,因爲unique_ptr是一個STL對象。我如何實例化DLL中的對象並返回unique_ptr?
4.爲什麼定義接口或使用PIMPL有助於定義DLL接口?
我仍然必須將我的STL類轉換爲C樣式的對象。而在使用該DLL的項目中,我將不得不以某種方式再次在STL類中包裝C風格的對象。在這種情況下,我沒有看到使用接口或PIMPL的好處。另外,如果我定義了一個接口(具有純虛擬函數的類),那麼這與用__declspec(dllexport)聲明我的類中的函數是否具有相同的效果?
class IFoo
{
public:
virtual ~IFoo() = 0 {};
virtual void f1() = 0;
}
class Foo : public IFoo
{
public:
void f1();
//__declspec(dllexport) void f1(); //why use an interface if I can just declare the functions like this?
}
在現代C++ 11/14庫中如何解決DLL-STL問題?有沒有我可以看看的現代開源庫?
當然,選項並不是爲每個支持的編譯器混合編譯器版本或構建單獨的庫。 [Boost做到這一點](http://sourceforge.net/projects/boost/files/boost-binaries/1.59.0/) –
這可能是最簡單的解決方案,我想這樣做,因爲確保便攜DLL似乎是一場真正的鬥爭。一般來說,這對商業項目來說是否可以接受? – user3067395