2

C#でMongoose(http://code.google.com/p/mongoose/)バインディングを実装したい。いくつかの例がありますが、現在のバージョンでは機能しません。

これは私の現在の関数呼び出しです:

[DllImport("_mongoose",CallingConvention=CallingConvention.Cdecl)] private static extern IntPtr mg_start(int zero, Nullable, string options);

(動作中の)Cと同等のものは次のようになります。

const char *options[] = {
     "document_root", "/var/www",
     "listening_ports", "80,443s",
     NULL
   };
struct mg_context *ctx = mg_start(&my_func, NULL, options);

ここで、mg_startは次のように定義されます。

struct mg_context *mg_start(mg_callback_t callback, void *user_data,
                            const char **options);

Cの例全体はここにあります: https ://svn.apache.org/repos/asf/incubator/celix/trunk/remote_services/remote_service_admin_http/private/include/mongoose.h

const char *options[]をc#に転送するにはどうすればよいですか?

ありがとうございました

4

5 に答える 5

3
DllImport("_mongoose",CallingConvention=CallingConvention.Cdecl)]
private static extern IntPtr mg_start(IntPtr callback, IntPtr userData,
    [In][MarshalAsAttribute(UnmanagedType.LPArray,
                            ArraySubType=UnmanagedType.LPStr)] string[] options);

これは試していませんが、これでうまくいくと思います。C呼び出しでユニコードが必要な場合は、ArraySubTypeをLPWStrにする必要がある場合があります。LPStrにすることで、ANSIが得られます。

関数ポインタを実行していますか?それが本当の課題です。宣言とマーシャリングからではなく、ポインタの寿命の問題からです。mg_startが管理されていないバージョンのデリゲートを保持している場合、ドキュメントに記載されていることにもかかわらず、サンクがゴミを収集していることに気付く場合があります。これは非常に頻繁に発生するため、可能な場合は、そのスタイルのコードを使用しないように、基礎となる接着剤を再設計しました。

一般的に言って、APIが大量のコールバックを伴うおしゃべりなAPIである場合、コールバックに悩まされることになります。明確なマネージド/アンマネージド境界を使用して、はるかにチャットの少ない方法でAPIを実装するC ++/CLIライブラリを作成することをお勧めします。

于 2012-10-30T17:55:02.477 に答える
0

C#では、charはUnicode文字であるため、2バイトで構成されます。ここでは文字列を使用するオプションはありませんが、Encoding.ASCIIクラスを使用して、Unicode文字列のASCII表現をバイト配列として取得できます。

byte[] asciiString = Encoding.ASCII.GetBytes(unicodeString);

C#の配列は参照、別名Cのポインターであるため、コードを次のように記述できます。

byte[][] options = {
    Encoding.ASCII.GetBytes("document_root"),
    Encoding.ASCII.GetBytes("/var/www"),
    Encoding.ASCII.GetBytes("listening_ports"),
    Encoding.ASCII.GetBytes("80,443s"),
    null
};

constについては、読み取り専用インデクサーとバイトのプライベート配列を使用してラッパークラスを作成する以外に何もできませんが、これはあなたの場合には機能しません。

于 2012-10-30T17:39:45.850 に答える
0

C#のchar[]は文字列です。

char[]へのポインタを定義しているようです。Cでは、これは配列の配列ですよね?したがって、C#では次のようになります。

String[] options = {
 "document_root", "/var/www",
 "listening_ports", "80,443s",
 NULL
};

それが役に立てば幸い。

よろしく。

于 2012-10-30T17:32:54.633 に答える
0

試す

[DllImport("_mongoose",CallingConvention=CallingConvention.Cdecl)] 
private static extern IntPtr mg_start(int zero, IntPtr userData, string[] options);

として使用IntPtr.Zerouserdataます。とのようなもの

new [] { "document_root", "/var/www", "listening_ports", "80,443s", null }

オプションとして。

于 2012-10-30T17:33:14.813 に答える
0

プロジェクトページの機能で、C#バインディングの使用を提案したかっただけです。

  • PythonとC#のバインディング

これを試しましたか?

于 2012-10-30T17:40:41.803 に答える