web-dev-qa-db-ja.com

C#からC関数にconst char *を渡すにはどうすればよいですか?

C#アプリケーションから外部のDLL=からプレーンC関数を呼び出そうとしています。この関数は次のように定義されています。

_void set_param(const char *data)
_

今、私はこの関数を使用していくつかの問題があります:

  1. この "const"をC#コードで指定するにはどうすればよいですか? public static extern void set_param(sbyte *data)は「const」の部分を見逃しているようです。

  2. この関数を呼び出すときに、プレーンな8ビットのC文字列を渡すにはどうすればよいですか? set_param("127.0.0.1")を呼び出すと、エラーメッセージ"ca n't Convert to 'string' to 'sbyte'" *が返されます。

22
Elmi

ANSI文字セットを使用するように見えるので、次のようにP/Invokeを宣言できます。

[DllImport("yourdll.dll", CharSet = CharSet.Ansi)]
public static extern void set_param([MarshalAs(UnmanagedType.LPStr)] string lpString);

.NETマーシャラーは、文字列のコピーを作成し、データを適切なタイプに変換します。

不均衡なスタックでエラーが発生した場合は、C DLLと一致するように呼び出し規約を設定する必要があります。次に例を示します。

[DllImport("yourdll.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]

Windows API関数を使用した多くの例については、 pinvoke.net を参照してください。

Microsoftのドキュメンテーションの文字列に関するドキュメント も参照してください。

34
Matthew Watson

A const char*は単に.NETのstringです-管理対象側は(まだ)読み取り専用パラメーターの概念を理解していません。

これをP/Invokeコンテキストで使用している場合は、MarshalAs属性を宣言し、LPStrとしてマーシャリングする必要があります。結果の署名は、次のようになります。

[DllImport("SomeModule.dll")]
public static extern void set_param([MarshalAs(UnmanagedType.LPStr)]string lpString);

これもあります MSDNの記事 ネイティブ文字列を管理された環境にマーシャリングする方法の詳細について。

5
aevitas