简体   繁体   English

将字符串从C#传递到C ++ DLL,并在不同的返回类型上传递不同的文本编码

[英]Passing String from C# to C++ DLL different Text Encoding on different return Types

I hope somebody can explain what exactly the difference is: 我希望有人能解释到底有什么区别:

In my C# Programm I want to pass an String to an C++ Method. 在我的C#程序中,我想将字符串传递给C ++方法。 My Code in C# looks like this: 我在C#中的代码如下所示:

    [DllImport("Test.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)]
    public static extern String DoIt(String filename);

The inside of my C++ DLL looks like this: 我的C ++ DLL的内部看起来像这样:

__declspec(dllexport) CString DoIt(char* szFilename)
{
....
}

If I pass the String (like: C:\\temp\\my.txt) it becomes malformed =>"Ôœ&°8é-". 如果我传递字符串(例如:C:\\ temp \\ my.txt),它将变得格式错误=>“Ôœ&°8é-”。

Now comes the confusings part I can't literly understand. 现在是我无法理解的令人困惑的部分。 If I change the return Type from CString to char* everything is fine. 如果我将返回类型从CString更改为char *,一切都很好。

__declspec( dllexport ) char* DoIt(char* filename)

Why is that so? 为什么会这样? The CharSet in C# is already set to Ansi to Marshal the String into the right Type. C#中的CharSet已设置为Ansi,以将字符串编组为正确的Type。 I cannot figure out where the connection between the return Type and my passing String is. 我无法弄清楚返回类型和传递的String之间的连接在哪里。

If you need more information just let me know. 如果您需要更多信息,请告诉我。

Both versions of your code are wrong. 您的代码的两个版本都是错误的。 You certainly can't pass CString as an interop type. 您当然不能将CString作为互操作类型传递。 You to use simple types for interop, not C++ classes. 您要对互操作使用简单类型,而不是C ++类。

The error when you use char* is more subtle. 使用char*时的错误更加细微。 In that scenario there are two problems. 在那种情况下,有两个问题。

Firstly, with a string return type on the C# side, the pinvoke marshaller assumes that the returned string was allocated with CoTaskMemAlloc and will call CoTaskMemFree to deallocate it once it has been copied. 首先,对于C#端的string返回类型,pinvoke编组假定返回的字符串是使用CoTaskMemAlloc分配的,并且一旦复制后将调用CoTaskMemFree进行释放。

Secondly, although we can't see it, your C++ code almost certainly returns a pointer to a buffer owned by a local variable in the C++ function. 其次,尽管我们看不到它,但是您的C ++代码几乎可以肯定会返回一个指向C ++函数中局部变量拥有的缓冲区的指针。 Obviously this local variable goes out of scope when the function returns and so the pointer becomes invalid. 显然,该局部变量在函数返回时超出范围,因此指针变为无效。

Some options: 一些选项:

  1. Have the caller locate the string buffer and let the callee populate it. 让调用者找到字符串缓冲区,然后让被调用者填充它。
  2. Allocate the returned char* using CoTaskMemAlloc and so meet the expectations of the C# code. 使用CoTaskMemAlloc分配返回的char* ,从而满足C#代码的期望。
  3. Use the COM BSTR type which the pinvoke marshaller does understand. 使用pinvoke编组不能理解的COM BSTR类型。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM