2009-05-17 165 views
6

我認爲這個問題是我的C++函數裏面,但我想在C++ DLL這個在C#中的std :: string?

C++函數:

bool __declspec(dllexport) OpenA(std::string file) 
{ 
return true; 
} 

C#代碼:

[DllImport("pk2.dll")] 
public static extern bool OpenA(string path); 

    if (OpenA(@"E:\asdasd\")) 

我得到一個異常的記憶是腐敗的,爲什麼?

如果我刪除std :: string參數,它的效果很好,但與std :: string它不起作用。

+0

也許你可以解決它通過一個託管的C++橋解開字符串? [這裏](http://stackoverflow.com/questions/267057/creating-a-mixed-mode-c-bridge-from-c-to-c)是關於這個問題的SO問題。 – FeatureCreep 2009-05-17 13:11:58

回答

13

std :: string和c#字符串互不兼容。據我所知,c#字符串相當於在C++中通過char*wchar_t*就interop而言。
其中一個原因是std :: string可能有很多不同的實現,而c#不能假定你正在使用任何特定的實現。

+4

更不用說std :: string也是一個模板,它爲互操作打開了另一個有趣的蠕蟲罐。 – 2009-05-17 13:04:07

+1

最正確的方法是使用char *並從中創建std :: string。如果你想返回一個std :: string到C#,你必須用CoTaskMemAlloc分配一個大小爲std :: string的size()+ 1,然後memcpy std :: string的data()到這個緩衝區並返回它。簡單。注意:你必須使用CoTaskMemAlloc! – 2015-03-10 00:54:08

6

嘗試是這樣的:

bool __declspec(dllexport) OpenA(const TCHAR* pFile) 
{ 
    std::string filename(pFile); 
    ... 
    return true; 
} 

你還應該指定適當的字符集(UNICODE/ANSI)在你的DllImport屬性。

另外,與您的編組問題無關,通常會將std:string作爲const引用傳遞:const std:string & filename。

+1

如果定義了_UNICODE,那麼std :: string將無法編譯。可能會更好地執行#ifdef並使用std :: wstring,或者簡單地根據_UNICODE對tstring進行typedef。 – 2009-05-17 16:21:32

1

不可能以您嘗試的方式編組C++ std :: string。你真正需要做的是寫一個包裝函數,它使用普通的老式const char*並轉換爲引擎蓋下的std :: string。

C++

extern C { 
    void OpenWrapper(const WCHAR* pName) { 
    std::string name = pName; 
    OpenA(name); 
    } 
} 

C#

[DllImport("pk2.dll")] 
public static extern void OpenWrapper([In] string name); 
0

我知道這個題目是一點點老了,但對未來的Google,這也應該工作(不使用C中的char * ++)

C# :

public static extern bool OpenA([In, MarshalAs(UnmanagedType.LPStr)] path); 

C++:

bool __declspec(dllexport) OpenA(std::string file); 
相關問題