C# PinVokeStack异常的解决方案(从C调用非托管C+;+;dll)-VS2010
我花了一天的时间来解决这个问题,我不希望其他人也这么做。问题和解决方案如下:C# PinVokeStack异常的解决方案(从C调用非托管C+;+;dll)-VS2010,c#,windows,dll,pinvoke,dllimport,C#,Windows,Dll,Pinvoke,Dllimport,我花了一天的时间来解决这个问题,我不希望其他人也这么做。问题和解决方案如下: 问题:当你试图在C++代码中使用C++的DLL方法时,你会遇到PvIOKESTACKEXIT异常。下面是您在示例中看到的典型声明 不起作用的示例 (C++ .h file) extern "C" { __declspec(dllexport) int Addints(int a, int b); } (C++ .cpp file) extern int Addints(int a, int b) {
问题:当你试图在C++代码中使用C++的DLL方法时,你会遇到PvIOKESTACKEXIT异常。下面是您在示例中看到的典型声明
不起作用的示例(C++ .h file)
extern "C" {
__declspec(dllexport) int Addints(int a, int b);
}
(C++ .cpp file)
extern int Addints(int a, int b) {
return a+b;
}
(C# .cs file)
[DllImport("testdll.dll")]
static extern int Addints(int a, int b);
static void Main(string[] args)
{
Console.WriteLine("Hello world lets add some stuff");
Int32 a = 3;
Int32 b = 5;
Console.WriteLine(Addints(a,b));
}
当你运行这个程序时,它会抱怨你已经平衡了堆栈(在NOE上!),并且你真的不应该继续。它还说,您应该检查方法的签名,以确保它们匹配
谎言都是谎言
修复:您需要做的是在DLLImport语句中添加一个~小东西,如下所示:
这是修复方法
[DllImport("testdll.dll", CallingConvention = CallingConvention.Cdecl)]
static extern int Addints(int a, int b);
是的,那个叫会议的事?真的很重要
其他一些提示:-确保为同一目标构建dll和C#exe。Win32和x86(例如)分别
-确保dll是使用/clr选项(项目属性-配置属性-常规)构建的
-请记住,C++的INT、String、String可能在边界的另一侧不相同(检查以查看类型是如何匹配的) -要获得一个真正好的分步示例,请查看程序snotebook.wordpress.com/2010/01/18/calling-a-cpp-dll-from-cs简短版本: 确保C#中的DllImport语句包含设置为CallingConvention.Cdecl的CallingConvention参数 有关更多详细信息,请参见上文 我不想这么做,但你的答案不是全部。默认情况下,C/C++使用Cdecl调用约定,因此您必须修改的原因很明显
实际的解决方案只需在C++代码中声明调用约定。< /P>
还有其他调用约定,因此您的答案实际上取决于C/C++非托管代码的调用约定 我怀疑VS2008的原因更多地与.NETFramework3.5有关,而不是其他任何东西 只需将您的函数更改为:__declspec(dllexport) int __stdcall Addints(int a, int b);
是的,很可爱。不过,它也能起作用——仔细阅读我写的内容,我说这是对“示例中给出的典型声明”的修正。你可能会问什么样的例子?这里有几个: dotnetperls.com/dllimport
程序员snotebook.wordpress.com/2010/01/18/calling-a-cpp-dll-from-cs/
blogs.msdn.com/b/jonathanswift/archive/2006/10/02/780637.aspx
msdn.microsoft.com/en-us/library/aa984739(VS.71).aspx
msdn.microsoft.com/en-us/library/26thfadc.aspx
www.codeguru.com/columns/kate/article.php/c3947
www.apachetechnology.net/KC/NativeDLL2Net.aspx
到目前为止,我还没有看到这种变体。然而,如果它们都能起作用,那么问题在哪里呢?如果你需要荣誉,那就来吧:好极了!荣誉现在人们有两种选择。哦,顺便说一句,你的“答案不是全部答案”: 您还需要更改cpp文件
再一次-我使用.Net 4访问VS2010(不确定您在评论VS2008时指的是什么)。很抱歉,前面的平台调用数据类型链接已断开,请参见:
您应该能够在Windows上使用默认的呼叫约定,如果无法使用,则说明存在其他问题。我当然可以导入非托管库,而无需声明调用约定。您应该做的是将此作为一个问题,然后提供“修复”部分作为下面的答案。这是一个问答网站,不是论坛。请看,我应该添加我用来定义8、16、32和64有符号和无符号数字的库。NET恰好定义了相同的类型。你好,第一个帖子巨魔。。。Ramhound,我的配置是VS2010,XP上的.NET4。我的设置没有问题。SwDevMan81,天哪,如果你等一会儿而不是跳到我身上,你会看到我这么做:P和拉米?是的,我都试过了,但你还是没有领会我文章的要点。只是想帮助别人,如果你不喜欢的话,很抱歉。我有完全相同的设置,我的非托管库可以通过声明调用约定导入,你的解决方案不是全部答案。继续给人们“提示”但是忽略了您应该简单地匹配C/C++非托管代码的调用约定的部分。我很清楚您使用的是Visual 2010,我也在使用它,与您列出的设置完全相同。我关于VisualStudio2008(.NETFramework 3.5)的声明与代码正常工作的原因有关。
(C++ .h) extern "C" {
__declspec(dllexport) int __stdcall Addints(int a, int b); }
(C++ .cpp) int __stdcall Addints(int a, int b) {
return a+b; }