2016-10-24 109 views
4

我一直在尋找我的問題的答案,但似乎大多數人都感興趣將std :: string跨越.dll邊界。但我更感興趣的是在我創建的.dll類中使用std :: string。你可以在第三方DLL中使用std :: string嗎?

我將我的.dll(電子郵件)發佈給論壇上的一組人,因此我的問題是您可以在.dll中使用std :: string,而不需要像編譯器一樣的限制必須相同,版本,CRT需要相同,等等。

你能給我舉例說明什麼是不安全的,什麼是安全的?

示例:對於「下載程序」使用SetSender函數,這是否安全?

Mail.h

class _declspec(dllexport) Mail { 

    struct ENVELOPE { 
     std::wstring SenderEmail; //Should the type be LPWSTR or can it safely be std::wstring 
     LPWSTR SenderName; 

    }Envelope; 

public: 
    int SetSender(LPWSTR SenderEmail); 
    Mail(); 
    ~Mail(); 

}; 

Mail.cpp

#include "stdafx.h" 
#include "Mail.h" 

int CoffeeBeans::Mail::SetSender(LPWSTR Email) { 
//Pass LPWSTR instead of std::wstring across .dll boundary 

    if (Email == nullptr || lstrcmp(Email, L"") == 0) { 
     throw L"Email was either nullptr or empty."; 
    } 

    this->Envelope.SenderEmail = SenderEmail; 
    return 0; 


} 
+0

我會說C字符串肯定是安全的。那麼爲什麼不傳遞一個只讀的C字符串呢? –

+0

我在過去曾經使用過一個.dll文件,當我使用一個帶std :: string(mysqlC++庫)的函數時,我的程序崩潰了,我不得不重新編譯dll來使它工作。 – tkausl

+1

@PaulStelian謝謝,但是你是非常正確的,我一直在傳遞wchar *而不是const wchar *的壞習慣。 –

回答

2

使用指針像LPWSTR,或wchar_t*等字符串緩衝區將永遠是安全的,只要你的DLL的代碼是不是調用未指定的行爲(內存分配正確,指針初始化,不傳遞指向本地緩衝區的指針等)。使用std::string將是安全的只有只要您的DLL和主機使用相同的CRT版本。如果版本不同,您的字符串可能導致任何執行階段的訪問衝突(通常發生在字符串銷燬)。你可以通過發佈你的dll源文件或者爲所有現有的CRT編譯不同的dll版本來確保CRT匹配(例如,Oracle爲它們的庫這樣做)。如果客戶端不使用C++,這種方法當然不起作用。

+0

這正是我今天第三方DLL所體驗到的。但是有沒有關於這個問題的MS文檔? – Trantor

+0

@Trantor我還沒有看到任何此類文件。 – Ari0nhh

相關問題