制作 C++ C# 的 DLL

发布于 2024-12-08 20:58:21 字数 659 浏览 0 评论 0原文

我制作了一个非常简单的 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

Saygoodbye 2024-12-15 20:58:21

您收到的错误消息确实包含一个很好的建议:

检查 PInvoke 签名的调用约定和参数是否与目标非托管签名匹配。

您应该在双方(C++ dll 和 C# 程序集)上指定相同的调用约定。在 C++ 中,您可以通过在函数声明前添加 __cdecl、__stdcall 等之一来指定它。


extern "C"
{
  __declspec(dllexport) int __stdcall Try(int v)
  {
    return 10 + v;
  }
}

在 C# 方面,您可以使用 DllImport 属性指定它,默认值是 CallingConvention.StdCall,它对应于 C++ 中的 __stdcall,所以,它看起来像您在 C++ 端有一个 __cdecl。要解决此问题,请在 DLL 中使用 __stdcall(如上所示),或在 C# 中使用 CDecl,如下所示:


class Program
{
    [DllImport("TestLib.dll", CallingConvention=CallingConvention.Cdecl)]
    public static extern int Try(int v);

    static void Main(string[] args)
    {
        Console.WriteLine("Wynik: " + Try(20));
        Console.ReadLine();
    }
}

The error message you've got contains a good advice indeed:

Check that the calling convention and parameters of the PInvoke signature match the target unmanaged signature.

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.


extern "C"
{
  __declspec(dllexport) int __stdcall Try(int v)
  {
    return 10 + v;
  }
}

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:


class Program
{
    [DllImport("TestLib.dll", CallingConvention=CallingConvention.Cdecl)]
    public static extern int Try(int v);

    static void Main(string[] args)
    {
        Console.WriteLine("Wynik: " + Try(20));
        Console.ReadLine();
    }
}

牛↙奶布丁 2024-12-15 20:58:21

C和C++中默认的调用约定是__cdecl; .NET P/Invoke 使用的默认调用约定是 __stdcall ——您需要协调这两者。

  • 要么按照 Hans 的建议创建您的本机函数 __stdcall

    __declspec(dllexport) int __stdcall Try(int v)
    
  • 或者让您的托管 P/Invoke 签名使用 __cdecl

    [DllImport("TestLib.dll", CallingConvention = CallingConvention.Cdecl)]
    公共静态 extern int Try(int v);
    

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:

    __declspec(dllexport) int __stdcall Try(int v)
    
  • Or make your managed P/Invoke signature use __cdecl:

    [DllImport("TestLib.dll", CallingConvention = CallingConvention.Cdecl)]
    public static extern int Try(int v);
    
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文