4

ちょっと初心者の質問かもしれませんが、それは過去数時間 (または数日) の間、私をピクルスに陥れているものです...

.NET Framework 4.0 のコードで DLL からメソッドを呼び出しています

  [DllImport("xeneth.dll")]
    public static extern ErrorCode XC_GetFrame(Int32 h, FrameType type, ulong ulFlags, IntPtr buff, uint size);

そして、ここでそれを使用します:

if (XC_GetFrame(myCam, XC_GetFrameType(myCam), 0, IntPtr.Zero, (uint)fs) != ErrorCode.E_NO_FRAME)

ただし、これを .NET 4.0 で実行すると P/INVOKE エラーが発生しますが、3.5 でこれを実行してもこのエラーは発生しません。私と別のプログラマーがコードを調べた後、4.0 での IntPtr の動作が異なっていることが判明したようです。

アプリケーションに必要ないくつかの機能は 4.0 でしか利用できないため、私のアプリケーションは .NET 4.0 で実行する必要があります ...

私が見落としている、または単に含めるのを忘れているものはありますか?

どんな考えでも大歓迎です!

トム

アップデート:

ネイティブ宣言:

virtual ErrCode XCamera::GetFrame(FrameType type, unsigned long ulFlags, void *buffer, unsigned int size)

エラー: PInvoke 関数 'DLLTest!DLLTest.Form1::XC_GetFrameType' の呼び出しにより、スタックのバランスが崩れています。これは、マネージド PInvoke 署名がアンマネージド ターゲット シグネチャと一致しないことが原因である可能性があります。PInvoke シグネチャの呼び出し規約とパラメーターがターゲットのアンマネージド シグネチャと一致することを確認します。

4

3 に答える 3

9

これの2つの一般的な原因:

  1. 呼び出し規約の不一致。C#コードはデフォルトの。を使用しますstdcall。おそらく、ネイティブコードはを使用しcdeclます。属性に追加CallingConvention=CallingConvention.Cdeclしてみてください。DllImport
  2. パラメータリストの不一致(以下を参照)。

.net 3.5ではこのエラーが発生しないため、コードに問題がないことを気にしないでください。.net 4でのエラー検出の方が優れているため、エラーが表示されるだけです。しかし、あなたのコードはすべての.netバージョンで壊れています。


C++仮想メソッドのネイティブ定義は次のとおりです。

virtual ErrCode XCamera::GetFrame(FrameType type, unsigned long ulFlags, 
    void * buffer, unsigned int size);

pinvoke呼び出しの最初のパラメーターとしてオブジェクトポインターを渡しているようです。それが問題かどうかを知るためにエクスポートされたときに仮想関数がどのように処理されるかについては十分にわかりませんが、それはうまくいくと思います。おそらく、オブジェクトをインスタンス化するためにプレーンなC関数をエクスポートしました。

私が見る他の問題は、WindowsではC /C++longが32ビットであるということです。AC#longは64ビットです。これは、の正しい宣言がC#コードの場合ulFlagsと同じであることを意味します。uint

于 2012-03-27T21:37:04.950 に答える
3

私の頭の上から、両方のプロジェクトのビットネスをチェックしましたか? 一方が 64 ビットで、もう一方が 32 ビットの場合、エラーが発生します。最近のバージョンでは、C# プロジェクトのデフォルトが Any CPU から x86 に変更されたことに注意してください。これは x86 OS では問題になりませんが、x64 OS では大きな違いになります。

さらに、エラーのテキストをできるだけ多く含める必要があります。個人情報を保護するための検閲は問題ありませんが、エラー番号とテキストは非常に役立ちます。さらに、作業するときexternは、任意のタイプの両方の定義を含めて、structそれらが同等であることを確認すると便利です。(別の一般的な問題)。

于 2012-03-27T21:27:42.417 に答える
1

たぶん、より良い質問は、なぜ以前は機能していたのかということです。あなたが提供した宣言:

virtual ErrCode XCamera::GetFrame(FrameType type, unsigned long ulFlags, void * buffer, unsigned int size)

に対応する .NET タイプがありますFrameType, uint, IntPtr, uint

Windows ではunsigned long32 ビット型ですが、C#ulongでは 64 ビット型です。

于 2012-03-27T21:42:27.023 に答える