2009-05-17 90 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); 
相关问题