制作 C++ C# 的 DLL
我制作了一个非常简单的 Dll,如下所示:
extern "C"
{
__declspec(dllexport) int Try(int v)
{
return 10 + v;
}
}
然后我想在我的 C# 应用程序中使用它:
class Program
{
[DllImport("TestLib.dll")]
public static extern int Try(int v);
static void Main(string[] args)
{
Console.WriteLine("Wynik: " + Try(20));
Console.ReadLine();
}
}
它一直在工作,直到我尝试传递参数。现在我在运行时出现以下错误:
调用 PInvoke 函数 “ConsoleApplication2!ConsoleApplication1.Program::Try”不平衡 堆栈。这可能是因为托管 PInvoke 签名确实 与非托管目标签名不匹配。检查调用是否正确 PInvoke 签名的约定和参数与目标匹配 非托管签名。
我不知道问题出在哪里。
I have made a very simple Dll like this:
extern "C"
{
__declspec(dllexport) int Try(int v)
{
return 10 + v;
}
}
Then I want to use it in my C# app:
class Program
{
[DllImport("TestLib.dll")]
public static extern int Try(int v);
static void Main(string[] args)
{
Console.WriteLine("Wynik: " + Try(20));
Console.ReadLine();
}
}
It was working until I have tried to pas parameter. Now I have following error at runtime:
A call to PInvoke function
'ConsoleApplication2!ConsoleApplication1.Program::Try' has unbalanced
the stack. This is likely because the managed PInvoke signature does
not match the unmanaged target signature. Check that the calling
convention and parameters of the PInvoke signature match the target
unmanaged signature.
I have no idea where is the problem.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您收到的错误消息确实包含一个很好的建议:
您应该在双方(C++ dll 和 C# 程序集)上指定相同的调用约定。在 C++ 中,您可以通过在函数声明前添加 __cdecl、__stdcall 等之一来指定它。
在 C# 方面,您可以使用 DllImport 属性指定它,默认值是 CallingConvention.StdCall,它对应于 C++ 中的 __stdcall,所以,它看起来像您在 C++ 端有一个 __cdecl。要解决此问题,请在 DLL 中使用 __stdcall(如上所示),或在 C# 中使用 CDecl,如下所示:
The error message you've got contains a good advice indeed:
You should have the same calling convention specified on both sides (C++ dll and C# assembly). In C++ you can specify it by prepending function declaration with one of __cdecl, __stdcall, etc.
On the C# side you specify it with DllImport attribute, the default one is CallingConvention.StdCall which corresponds to __stdcall in C++, so, it looks like you have a __cdecl on the C++ side. To fix the issue either use __stdcall in your DLL as shown above, or use CDecl in C# like this:
C和C++中默认的调用约定是
__cdecl
; .NET P/Invoke 使用的默认调用约定是 __stdcall ——您需要协调这两者。要么按照 Hans 的建议创建您的本机函数
__stdcall
:或者让您的托管 P/Invoke 签名使用
__cdecl
:The default calling convention in C and C++ is
__cdecl
; the default calling convention used by .NET P/Invoke is__stdcall
-- you need to reconcile these two.Either make your native function
__stdcall
, as Hans suggested:Or make your managed P/Invoke signature use
__cdecl
: