1

重複の可能性:
PInvoke関数'[…]'の呼び出しでスタックのバランスが崩れています

ac#プログラム(WPF、または例としてコンソールアプリ)で使用するために、c ++で記述されたいくつかの関数をラップしようとしていますが、実行時の例外が発生します。

これは(C#プロジェクトのC ++プロジェクトの)コンパイルの問題だと思います。C#プロジェクトのプラットフォームターゲットを変更すると、さまざまな例外が発生します。プラットフォームターゲットがx64の場合、

間違った形式のプログラムを読み込もうとしました。(HRESULTからの例外:0x8007000B)

x86としてコンパイルしようとすると、次のようになります。

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

私はWindows764でVS2010を実行しています。

これを解決する方法についてのアイデアがあれば幸いです。

これが私がすることです:

c++コード。cpp:

int create(int Handle)
{
    return 1;
}

およびh:

#define EXPORT_DLL __declspec(dllexport)

extern "C"
{
EXPORT_DLL int create(int Handle);
}

次に、2番目のC#プロジェクトで、このdllを呼び出します。ここで、c++プロジェクトの名前はwrapAttemptCです。

namespace Wrapper
{
    internal class IWrapper
    {
        const string SHADOW_DLL_NAME = "wrapAttemptC.dll";

        [DllImport(SHADOW_DLL_NAME)]
        public static extern int create(int Handle);
    }
    public class CWW
    {
        public CWW(){}

        public int Connect(int cam)
        {
            return IWrapper.create(cam);
        }
    }
}

次に、c ++プロジェクトで作成されたDLLファイルをこのc#プロジェクトとアプリc#プロジェクト(WPF)のbin / Debugに入れて、呼び出してみます

CWW cww = new CWW();
cww.Connect(5);
4

1 に答える 1

2

C ++でエクスポートされた関数cdeclのデフォルトの呼び出し規約はですが、DllImport属性のデフォルトの呼び出し規約はWinApi(デフォルトはstdcall)です。そのため、スタックを実際に台無しにする可能性のある不一致があります。呼び出し規約を属性、C ++関数宣言、またはそれ以上の両方で明示的に記述してみてくださいDllImport(一致するように)。このような:

EXPORT_DLL __stdcall int create(int Handle);

そしてあなたのC#プロジェクトでは:

[DllImport(SHADOW_DLL_NAME, CallingConvention = CallingConvention.StdCall)]
于 2012-05-15T14:51:02.690 に答える