0


現在、C# Windows アプリケーションから Win32 DLL[Native] を呼び出すという問題が発生しています。

私はここまで来ました。

C++ ソース:

extern "C" __declspec(dllexport) int PlaceSound(__in DWORD frequence, __in DWORD duration)
{
    Beep(frequence, duration);
    return 0;
}

C# ソース:

[DllImport("SampleLib.dll")]
    public extern static int PlaceSound(int Freq, int Dura);

 public form1 { InitializeComponements; PlaceSound(150, 500); }

デバッグ時にサウンドを受け取りますが、ライブラリが整数値を返すと、ピンボークが発生するようです。

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

私は何を間違っていますか?

4

2 に答える 2

10

C++ コンパイラcdeclのデフォルトの呼び出し規約は ですが、p/invoke のデフォルトの呼び出し規約は ですstdcall。この不一致が、表示されるメッセージの理由です。

また、100% 正しくするにDWORDは、 は符号なし整数であり、 と一致する必要がありuintます。

したがって、次のようにインポートする必要があります。

[DllImport("SampleLib.dll", CallingConvention=CallingConvention.Cdecl)]
public extern static int PlaceSound(uint Freq, uint Dura);
于 2012-05-08T16:29:11.650 に答える
3

まあ、PInovke は通常 __stdcall/WINAPI/CALLBACK/PASCAL 呼び出し規約にデフォルト設定されています。関数が WINAPI になるように C++ ソースを変更するか、cdecl 呼び出しメソッドを使用するように PInvoke 宣言関数を変更する方法がある可能性があります。簡単にするために、私は常にWINAPIを使用しています。

extern "C" __declspec(dllexport) int WINAPI PlaceSound(__in DWORD frequence, __in DWORD duration)
{
    Beep(frequence, duration);
    return 0;
}
于 2012-05-08T16:31:45.963 に答える