为C#编写C ++ DLL [英] Making C++ DLL for C#

查看:173
本文介绍了为C#编写C ++ DLL的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经做了一个非常简单的Dll:

  externC
{
__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();
}
}

它一直工作,直到我尝试了pas参数。现在我在运行时出现以下错误:


调用PInvoke函数
'ConsoleApplication2!ConsoleApplication1.Program :: Try'has不平衡
的堆栈。这可能是因为管理的PInvoke签名的
与非托管目标签名不匹配。检查调用
约定和PInvoke签名的参数是否匹配目标
非管理签名。


我有不知道问题在哪里

解决方案

您的错误信息确实包含了一个很好的建议:



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


你应该在两边指定相同的调用约定(C ++ dll和C#assembly)。在C ++中,您可以使用__cdecl,__stdcall等之一的函数声明来指定它。

 

externC
{
__declspec(dllexport)int __ stdcall Try(int v)
{
return 10 + v;
}
}

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

 

class程序
{
[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();
}
}


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.

解决方案

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();
    }
}

这篇关于为C#编写C ++ DLL的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆