次の問題があります。
アンマネージド C++ dll から関数を呼び出す C# アプリがあります。dll には、構造体に格納される C# と C++ (基本的には値とその型のリスト) の間のインターフェイスを作成する初期化関数があります。
その後、C# アプリが dll に送信するコールバック関数があり、dll はこれを時々呼び出し、インターフェイスで定義された構造体変数 (またはバイト配列) を返します。
私の質問: この構造体をどのように渡し、マーシャリングしますか? 構造体自体を渡すことは可能ですか、それともバイト配列を渡す必要がありますか?
バイト配列を渡す場合、C# アプリに返されるときにどのようにマーシャリングしますか?
私が今持っているもの:
C# アプリで:
コールバック関数のマーシャリング:
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate void ProcessOutputDelegate(???); // not sure what should be here.
dll 関数のインポート:
[DllImport("MyDLL.dll", CallingConvention=CallingConvention.Cdecl)]
public static extern void Test(ProcessOutputDelegate ProcessOutput);
dll 関数の呼び出し:
ProcessOutputDelegate process = new ProcessOutputDelegate(ProcessOutput);
new thread(delegate() { Test(process); } ).Start();
出力の処理:
public void ProcessOutput(???)
{
// Assume we have a list of values that describes the struct/bytes array.
}
C++ dll には、次の構造体があります (これは例であり、異なるランタイムで別の dll が呼び出される可能性があるためです)。
struct
{
int x;
double y;
double z;
} typedef Interface;
そして、C# アプリによって呼び出される関数:
__declspec(dllexport) void Test(void (*ProcessOutput)(Interface* output))
{
int i;
Interface* output = (Interface*)malloc(sizeof(Interface));
for (i = 0; i < 100; i++)
{
sleep(100);
output->x = i;
output->y = i / 2;
output->z = i / 3;
ProcessOutput(output); // or generate a bytes array out of the struct
}
}
編集:
C# アプリケーションは一般的な GUI であり、c++ dll によって実行される重い計算を表示することを想定しています。初期化プロセスでは、dll は GUI に提示すべき変数 (およびその型) を伝え、GUI はこれらの指示に従って構築されます (ここでも、計算と変数は変更される可能性があり、値は int、float、float の場合があります)。文字...)。その後、dll が実行され、数ステップごとにコールバック関数が呼び出されて GUI が更新されます。これは、このアイデアを実装するすべての dll で動作するはずです: インターフェイスを生成し、このインターフェイスに従って情報を送信します。