c#动态调用C++代码。对PInvoke函数“InteropDemo!InteropDemo.Program+Add::Invoke”的调用导致堆栈不对称。
在使用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;
}
------解决方案--------------------
把CallingConvention = CallingConvention.Cdecl删除,用默认的那个,你这里不是Cdecl调用方式,C++原型里面有__stdcall的,都是用的CallingConvention.StdCall(默认的)
------解决方案--------------------int __stdcall,人家是stdcall,你非得搞成 CallingConvention.Cdecl
------解决方案--------------------在你的Add委托定义前加一条
[UnmanagedFunctionPointerAttribute(CallingConvention.StdCall)]