2017-04-13 14 views
2

VB.NETアセンブリのP/Invoke宣言をC#から使用しようとすると、string引数がref string引数になっています。より密接に検査すると、例えば、 「VBByRefStr:アンマネージコード内の文字列を変更するには、Visual Basic .NETを有効にする値を、そしてその結果がマネージコードに反映されていVB.NET P/Invoke宣言のVBByRefStrの理解

Public Declare Unicode Function RegDeleteValue Lib "advapi32.dll" Alias "RegDeleteValueW" (_ 
    ByVal hKey As IntPtr, ByVal lpValueName As String) As UInteger 

は私が読んMSDNオン

[DllImport(...)]public static extern uint RegDeleteValue(
    IntPtr hKey, [MarshalAs(UnmanagedType.VBByRefStr)] ref string lpValueName); 

にコンパイルされます。この値は、プラットフォームの呼び出しに対してのみサポートされています。これは、Visual BasicではByVal文字列の既定値です。

私はまだそれを取得しません。 VB.NETではなく、奇妙なVBByRefStr: - なぜそれが唯一のstring lpValueName C#で(​​ため Damien_The_Unbelieverが指摘したように、署名はRegDeleteValueように同じである編集pinvoke.netを参照)されましたか? VB.NETで<MarshalAs(UnmanagedType.LPWStr)>と宣言して、refをC#で回避する必要がありますか?それとも悪影響がありますか?

+0

これは大きな違いはありませんが、あなたのピンボケリンクは* different *機能です。 'RegDeleteKey'!=' RegDeleteValue'です。 advapi32内の['RegDeleteValue'](https://msdn.microsoft.com/en-us/library/windows/desktop/ms724851(v = vs.85).aspx)のPInvokeページが見つかりません –

+0

私が 'RegDeleteValue'を見つけなかったときに私がpinvokeで' RegDeleteKey'で終わったように見えます。混乱させて申し訳ありません。しかし、主な所見は 'RegDeleteKey'でも同じです:-) –

答えて

3

これは、VB6 Declareステートメントとの下位互換性のためです。

ByVal x As Stringを使用すると、VB UTF-16「String」型をASCII表現に変換し、そのASCIIバッファへのポインタをそのパラメータに渡し、呼び出しが成功した後、そのバッファの内容を元のUTF-16文字列に変換し直します。

これは、その後、Unicode API呼び出しをサポートするようにVB.NETで拡張されました。しかし、VBByRefStr定数は、.NETで行われたマーシャリングがVB6のメソッドに正確に従わなければならないことを示していると思います。

UnmanagedType.LPWStrの標準マーシャリングを使用する場合は、属性を使用します。

+0

説明に感謝します!私はVB6スタイルの 'Declare'ステートメントを取り除き、代わりに' DllImport'を使うべきだと思います –

関連する問題