c#动态调用C++代码。对PInvoke函数“InteropDemo!InteropDemo.Program+Add::Invoke”的调用导致堆栈不对称。

xiao_xiaoli 2012-09-26 10:02:32
在使用C#动态调用C++动态链接的时候,出现了以下异常:
对 PInvoke 函数“InteropDemo!InteropDemo.Program+Add::Invoke”的调用导致堆栈不对称。原因可能是托管的 PInvoke 签名与非托管的目标签名不匹配。请检查 PInvoke 签名的调用约定和参数与非托管的目标签名是否匹配。

求解,谢谢

源代码为:
----NativeMethod.cs---------------------------
using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;


namespace InteropDemo
{
public static class NativeMethod
    {
        [DllImport("kernel32.dll", EntryPoint = "LoadLibrary")]
        public static extern int LoadLibrary(
            [MarshalAs(UnmanagedType.LPStr)] string lpLibFileName);

[DllImport("kernel32.dll", EntryPoint = "GetProcAddress")]
        public static extern IntPtr GetProcAddress(int hModule,
            [MarshalAs(UnmanagedType.LPStr)] string lpProcName);

[DllImport("kernel32.dll", EntryPoint = "FreeLibrary", CallingConvention = CallingConvention.Cdecl)]
        public static extern bool FreeLibrary(int hModule);
    }
}



------------------Program.cs-----------------------------------
using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;

namespace InteropDemo
{
class Program
{
//[DllImport("CppDemo.dll", EntryPoint = "Add", ExactSpelling = false, CallingConvention = CallingConvention.Cdecl)]
        //public static extern int Add(int a, int b); //DllImport请参照 MSDN


        static void Main(string[] args)
        {
            //1. 动态加载C++ Dll
int hModule = NativeMethod.LoadLibrary(@"C:\CppDemo.dll");
            if (hModule == 0) return;

            //2. 读取函数指针
            IntPtr intPtr = NativeMethod.GetProcAddress(hModule, "Add");

            //3. 将函数指针封装成委托
            Add addFunction = (Add)Marshal.GetDelegateForFunctionPointer(intPtr, typeof(Add));

            //4. 测试
Console.WriteLine(addFunction(1,2 )); //异常指示在此处的addFunction
Console.Read();

        }

        /// <summary>
        /// 函数指针
        /// </summary>
        /// <param name="a"></param>
        /// <param name="b"></param>
        /// <returns></returns>
        delegate int Add(int a, int b);
}
}


-----------------CppDemo.cpp-------------------------------------
#include "stdafx.h"

extern "C" __declspec(dllexport) int __stdcall Add(int a,int b)
{
return a+b;
}


...全文
670 12 打赏 收藏 转发到动态 举报
写回复
用AI写文章
12 条回复
切换为时间正序
请发表友善的回复…
发表回复
xiao助阵 2014-04-09
  • 打赏
  • 举报
回复
引用 9 楼 xuhu_it 的回复: 我也遇到了,在nf3.5下好着,在nf4下就报错。如果你想在nf4下使用那你就在你的委托方法前加上:[UnmanagedFunctionPointerAttribute(CallingConvention.Cdecl)] Bingo! 谢谢 [UnmanagedFunctionPointerAttribute(CallingConvention.Cdecl)] public delegate void TestDelegate(TestFuncDelegate td); TestDelegate testDelegate; public delegate void TestFuncDelegate( ); TestFuncDelegate testFuncDelegate; C++代码加了__stdcall只能对应使用DllImport,不加__stdcall用LoadLibrary(PS:用DllImport会卡着返回不了)
追逐光明的星 2013-04-03
  • 打赏
  • 举报
回复
引用 9 楼 xuhu_it 的回复:
我也遇到了,在nf3.5下好着,在nf4下就报错。如果你想在nf4下使用那你就在你的委托方法前加上:[UnmanagedFunctionPointerAttribute(CallingConvention.Cdecl)]
Bingo!
xuhu_it 2012-10-16
  • 打赏
  • 举报
回复
我也遇到了,在nf3.5下好着,在nf4下就报错。如果你想在nf4下使用那你就在你的委托方法前加上:[UnmanagedFunctionPointerAttribute(CallingConvention.Cdecl)]
qldsrx 2012-09-27
  • 打赏
  • 举报
回复
[System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)]
public struct HINSTANCE__ {

/// int
public int unused;
}

public partial class NativeMethods {

/// Return Type: HMODULE->HINSTANCE->HINSTANCE__*
///lpLibFileName: LPCWSTR->WCHAR*
[System.Runtime.InteropServices.DllImportAttribute("kernel32.dll", EntryPoint="LoadLibraryW")]
public static extern System.IntPtr LoadLibraryW([System.Runtime.InteropServices.InAttribute()] [System.Runtime.InteropServices.MarshalAsAttribute(System.Runtime.InteropServices.UnmanagedType.LPWStr)] string lpLibFileName) ;

}


/// Return Type: int
public delegate int FARPROC();

[System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)]
public struct HINSTANCE__ {

/// int
public int unused;
}

public partial class NativeMethods {

/// Return Type: FARPROC
///hModule: HMODULE->HINSTANCE->HINSTANCE__*
///lpProcName: LPCSTR->CHAR*
[System.Runtime.InteropServices.DllImportAttribute("kernel32.dll", EntryPoint="GetProcAddress")]
public static extern FARPROC GetProcAddress([System.Runtime.InteropServices.InAttribute()] System.IntPtr hModule, [System.Runtime.InteropServices.InAttribute()] [System.Runtime.InteropServices.MarshalAsAttribute(System.Runtime.InteropServices.UnmanagedType.LPStr)] string lpProcName) ;

}



[System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)]
public struct HINSTANCE__ {

/// int
public int unused;
}

public partial class NativeMethods {

/// Return Type: BOOL->int
///hLibModule: HMODULE->HINSTANCE->HINSTANCE__*
[System.Runtime.InteropServices.DllImportAttribute("kernel32.dll", EntryPoint="FreeLibrary")]
[return: System.Runtime.InteropServices.MarshalAsAttribute(System.Runtime.InteropServices.UnmanagedType.Bool)]
public static extern bool FreeLibrary([System.Runtime.InteropServices.InAttribute()] System.IntPtr hLibModule) ;

}

上面3个是帮你查到的函数定义,怎么看你的定义都不准确。
另外第一个LoadLibrary等价于LoadLibraryW,在WINAPI里面是别名。
qldsrx 2012-09-26
  • 打赏
  • 举报
回复
把CallingConvention = CallingConvention.Cdecl删除,用默认的那个,你这里不是Cdecl调用方式,C++原型里面有__stdcall的,都是用的CallingConvention.StdCall(默认的)
鲜血与铁锈 2021-06-16
  • 举报
回复
@qldsrx 还是前辈厉害啊
xiao_xiaoli 2012-09-26
  • 打赏
  • 举报
回复
@iyomumx
你好,谢谢你的回答,但是我在Add委托定义前加了,可是还是同样的异常。为了以防万一,想问下你加的地方时具体在哪行代码。不好意思哈
iyomumx 2012-09-26
  • 打赏
  • 举报
回复
在你的Add委托定义前加一条
[UnmanagedFunctionPointerAttribute(CallingConvention.StdCall)]
qldsrx 2012-09-26
  • 打赏
  • 举报
回复
你只给了测试代码,那三个导入函数的原型未给,无法做出判断。
xiao_xiaoli 2012-09-26
  • 打赏
  • 举报
回复
@bdmh
你好,就是是我个人的失误,可是如上所说一样,即使把class NativeMethod中的CallingConvention =CallingConvention.Cdecl删除,异常提醒还是一样的。所以请问该如何解决,谢谢
bdmh 2012-09-26
  • 打赏
  • 举报
回复
int __stdcall,人家是stdcall,你非得搞成 CallingConvention.Cdecl
xiao_xiaoli 2012-09-26
  • 打赏
  • 举报
回复
@qldsrx
你好,谢谢你的回答,不过把class NativeMethod中的CallingConvention =CallingConvention.Cdecl删除,异常显示还是一样的。

109,901

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧