5

C++ で記述された Win32 DLL から呼び出される C# 関数、コールバックがあります。発信者から UTF8 文字列が返されましたが、正しく受信できません。ハンガリーの特殊文字がすべて間違っています。

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

パラメータの型を に変更しIntPtrてコードを書いてみると、ちゃんと書いてくれます。しかし、これは非常に遅い解決策だと思います:

        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);

次のような属性を文字列パラメーターに書き込もうとしました。

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

誰も働いていませんでした。アドバイスをお願いします。前もって感謝します!

4

1 に答える 1

8

純粋なマネージ コードでこれを高速に実行する適切な方法はありません。常に文字列をコピーする必要があり、必要なバッファー サイズがわからないため、非常に厄介です。これを行うには、Windows 関数を pinvoke する必要があります。MultiByteToWideChar() は、主力コンバーター関数です。次のように使用します。

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);
于 2012-08-30T12:14:50.123 に答える