简体   繁体   English

C#回调接收UTF8字符串

[英]C# callback receiving UTF8 string

I have a C# function, a callback, called from a Win32 DLL written in C++. 我有一个C#函数,一个回调,从用C ++编写的Win32 DLL调用。 The caller gives me a UTF8 string, but I can't receive it properly, all the hungarian special characters go wrong. 调用者给了我一个UTF8字符串,但是我无法正确接收它,所有匈牙利语的特殊字符都出错了。

[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate int func_writeLog(string s);

When I changed the parameter type to IntPtr , and wrote the code, it writes properly. 当我将参数类型更改为IntPtr并编写代码时,它会正确写入。 But I find this is a very slow solution: 但我发现这是一个非常缓慢的解决方案:

        byte[] bb = new byte[1000];
        int i = 0;
        while (true)
        {
            byte b = Marshal.ReadByte(pstr, i);
            bb[i] = b;
            if (b == 0) break;
            i++;
        }
        System.Text.UTF8Encoding encodin = new System.Text.UTF8Encoding();
        var sd = encodin.GetString(bb, 0, i);

I tried to write some attribute to string parameter, like: 我试着给string参数写一些属性,比如:

  [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
  public delegate int func_writeLog([In, MarshalAs(UnmanagedType.LPTStr)] string s);

no one was working. 没有人在工作。 Any advice please? 有什么建议吗? Thanks in advance! 提前致谢!

There's no decent way to do this fast in pure managed code, it always requires copying the string and that's very awkward because you don't know the required buffer size. 在纯托管代码中没有很好的方法可以快速执行此操作,它总是需要复制字符串,因为您不知道所需的缓冲区大小,所以非常笨拙。 You'll want to pinvoke a Windows function to do this for you, MultiByteToWideChar() is the work-horse converter function. 你想要为你做一个Windows函数,MultiByteToWideChar()是work-horse转换器函数。 Use it like this: 像这样使用它:

using System.Text;
using System.Runtime.InteropServices;
...
    public static string Utf8PtrToString(IntPtr utf8) {
        int len = MultiByteToWideChar(65001, 0, utf8, -1, null, 0);
        if (len == 0) throw new System.ComponentModel.Win32Exception();
        var buf = new StringBuilder(len);
        len = MultiByteToWideChar(65001, 0, utf8, -1, buf, len);
        return buf.ToString();
    }
    [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
    private static extern int MultiByteToWideChar(int codepage, int flags, IntPtr utf8, int utf8len, StringBuilder buffer, int buflen);

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

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