【问题标题】:How to get unicode string from C++ to C# using PInvoke如何使用 PInvoke 将 unicode 字符串从 C++ 获取到 C#
【发布时间】:2013-01-15 16:23:48
【问题描述】:

我有以下 C++ 方法的签名。最后一个参数应该以 2 字节的 unicode 字符串形式返回设备名称。

int GetDeviceIdentifier(DWORD deviceIndex, WCHAR** ppDeviceName);

我使用以下签名封装到 C# 中。它有效,但我得到的字符串很奇怪。我做错了吗?

[DllImportAttribute("StclDevices.dll", EntryPoint = "GetDeviceIdentifier", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Unicode)]
public static extern int GetDeviceIdentifier(uint deviceIndex, StringBuilder ppDeviceName);

【问题讨论】:

    标签: c# string pinvoke unicode-string


    【解决方案1】:

    传递StringBuilder 参数将匹配WCHAR* 类型的C++ 参数。在这种情况下,内存将由 C# 代码通过设置字符串生成器对象的容量来分配。

    对于您的函数,看起来内存是由 C++ 代码分配的。因此双指针。所以你需要这个:

    [DllImportAttribute("StclDevices.dll", 
        CallingConvention=CallingConvention.Cdecl)]
    public static extern int GetDeviceIdentifier(
        uint deviceIndex, 
        out IntPtr ppDeviceName
    );
    

    你这样称呼它:

    IntPtr ppDeviceName;
    int retval = GetDeviceIdentifier(deviceIndex, out ppDeviceName);
    string DeviceName = Marshal.PtrToStringUni(ppDeviceName);
    

    【讨论】:

    • 现在我知道为什么我不喜欢 C++了。所有这些指针......感谢您的帮助。这工作得很好。我之前使用了容量为 128 的 StringBuilder,导致结果错误。
    【解决方案2】:
    [DllImportAttribute("StclDevices.dll", CharSet = CharSet.Unicode, ExactSpelling = true)]
    internal static extern Int32 GetDeviceIdentifier([In] UInt32 deviceIndex, [MarshalAs(UnmanagedType.LPTStr), Out] out String ppDeviceName);
    
    String ppDeviceName;
    NativeMethods.GetDeviceIdentifier(i, out ppDeviceName);
    

    如果您想坚持使用 StringBuilder,请改用它:

    [DllImportAttribute("StclDevices.dll", CharSet = CharSet.Unicode, ExactSpelling = true)]
    internal static extern Int32 GetDeviceIdentifier([In] UInt32 deviceIndex, [In, Out] StringBuilder ppDeviceName);
    
    StringBuilder ppDeviceName = new StringBuilder(255);
    NativeMethods.GetDeviceIdentifier(i, ppDeviceName);
    

    【讨论】:

    • 变体 1 将导致在 ppDeviceName 后面的指针上调用 CoTaskMemFree。变体 2 不正确,因为它是 C++ 代码中的双指针。 SetLastError 在这里不应该是 true。这是针对 Win32 API 函数的。
    猜你喜欢
    • 2020-05-08
    • 2011-03-02
    • 2010-11-02
    • 1970-01-01
    • 2011-06-11
    • 1970-01-01
    • 2019-01-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多