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:
对 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 调用约定。修改 C++ 源代码,使函数为 WINAPI,或者可能有办法修改您的 PInvoke 声明的函数以使用 cdecl 调用方法。为了方便,我总是使用 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 回答