1

私は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);
4

2 に答える 2

3

パラメータを渡すと、StringBuilderタイプがC++のパラメータと一致しますWCHAR*。その場合、メモリは文字列ビルダーオブジェクトの容量を設定することによって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);
于 2013-01-15T16:29:13.710 に答える
0
[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);
于 2013-01-15T16:32:18.170 に答える