2

C で記述された DLL (Point Gray Research Inc の FlyCapture API) を C# コードで使用しようとしていますが、常にランタイム エラーが発生します。ここに、DLL を使用した 2 つのコード サンプルがあります。

C++ コード:

void Callback(void* Param, int Message, unsigned long lParam)
{
    cout << Message << "\t" << lParam << endl;
}

int main(int argc, char *argv[])
{
    void *context;
    FlyCaptureCallback *callback = Callback;

    flycaptureCreateContext(&context);
    flycaptureModifyCallback(context, callback, NULL, true);

    _sleep(5000);

    flycaptureModifyCallback(context, callback, NULL, false);
    flycaptureDestroyContext(context);

    return 0;
}

C# コード:

[DllImport("pgrflycapture.dll")]
static extern int flycaptureCreateContext(void** pContext);

[DllImport("pgrflycapture.dll")]
static extern int flycaptureDestroyContext(void* context);

[DllImport("pgrflycapture.dll")]
static extern int flycaptureModifyCallback(void* context, IntPtr pfnCallback, void* pParam, bool bAdd);

delegate void FlyCaptureCallback(void* Param, int Message, uint lParam);

static void Callback(void* Param, int Message, uint lParam)
{
    Console.WriteLine(Message.ToString() + "\t" + lParam.ToString());
}

static void Main(string[] args)
{
    void *context;
    IntPtr callback = Marshal.GetFunctionPointerForDelegate((FlyCaptureCallback) Callback);

    flycaptureCreateContext(&context);
    flycaptureModifyCallback(context, callback, null, true);

    Thread.Sleep(5000);

    flycaptureModifyCallback(context, callback, null, false);
    flycaptureDestroyContext(context);
}

このプログラムの目的は、カメラ バスでイベントが発生したときにこの関数が呼び出されるように、コールバック関数を登録することです。次に、プログラムは 5 秒間待機し、コールバックをレジスタから削除します。C++ アプリケーションは正常に動作します。この 5 秒間にコンピューターからカメラを取り外すと、コンソールにメッセージが表示されます。一方、C# アプリケーションは、イベントが発生しない場合にのみ正常に動作するため、コールバック関数は呼び出されません。コンピューターからカメラを取り外そうとすると、Callback 関数が正常に呼び出され、正しい番号が画面に表示されますが、関数 flycaptureDestroyContext の実行中に Windows で「vshost32-clr2.exe が動作を停止しました」というメッセージが表示されます。

何か案は?ありがとう!

4

1 に答える 1

1

私はそれを持っている!問題は、API の関数 (flycaptureCreateContext、flycaptureModifyCallback、flycaptureDestroyContext) が C ヘッダーで __cdecl として宣言されていたことですが、DllImport ステートメントでは考慮していませんでした。修正された C# コードは次のとおりです。

[DllImport("pgrflycapture.dll", CallingConvention = CallingConvention.Cdecl)]
static extern int flycaptureCreateContext(void** pContext);

[DllImport("pgrflycapture.dll", CallingConvention = CallingConvention.Cdecl)]
static extern int flycaptureDestroyContext(void* context);

[DllImport("pgrflycapture.dll", CallingConvention = CallingConvention.Cdecl)]
static extern int flycaptureModifyCallback(void* context, FlyCaptureCallback pfnCallback, void* pParam, bool bAdd);

[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
delegate void FlyCaptureCallback(void* Param, int Message, uint lParam);

static void Callback(void* Param, int Message, uint lParam)
{
    Console.WriteLine(Message.ToString() + "\t" + lParam.ToString());
}

static void Main(string[] args)
{
    void *context;
    FlyCaptureCallback callback = (FlyCaptureCallback) Callback;

    flycaptureCreateContext(&context);
    flycaptureModifyCallback(context, callback, null, true);

    Thread.Sleep(5000);

    flycaptureModifyCallback(context, callback, null, false);
    flycaptureDestroyContext(context);
}

貴重なご協力をいただき、lnmx と Jim Mischel に感謝します。

于 2013-08-13T19:32:30.543 に答える