从 C# 调用 C++ 函数 - 堆栈不平衡 [英] Calling a C++ function from C# - unbalanced stack

查看:42
本文介绍了从 C# 调用 C++ 函数 - 堆栈不平衡的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个带有以下签名的非托管 C++ 函数:

I have a unmanaged C++ function with the following signature:

int function(char* param, int ret)

我正在尝试从 C# 调用它:

I am trying to call it from C#:

unsafe delegate int MyFunc(char* param, int ret);

...

int Module = LoadLibrary("fullpathToUnamanagedDll");
IntPtr pProc = GetProcAddress(Module, "functionName");
MyFunc func = (MyFunc)System.Runtime.InteropServices.Marshal.GetDelegateForFunctionPointer(pProc, typeof(MyFunc));

unsafe
{
    char* param = null;
    int ret = 0;
    int result = func(param, ret);
}

据我从旧的 C++ 项目规范中可以看出,param 的 null 和 ret 的 0 都是函数的有效输入.当我尝试调用它时,它似乎可以工作,但是在退出时出现以下错误:

As far as I can tell from the old C++ project specification both null for param and 0 for ret are valid inputs to the function. When I try to call it it seems to work, however upon exiting I get the following error:

检测到 PInvokeStackImbalance

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

A call to PInvoke function '...::Invoke' 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 tried pretty much anything I could think off (unsafe was last resort), however I can't find any way to run the function without getting unbalanced stack. Is there something else I could try?

推荐答案

IIRC,您需要使用调用约定来装饰委托签名.不幸的是,这只能通过 IL 或使用 Reflection.Emit 生成存根来完成.

IIRC, you need to decorate the delegate signature with a calling convention. Unfortunately, this can only be done via IL or generating the stub with Reflection.Emit.

你可以试试这个:

protected static Type MakeDelegateType(Type returntype, List<Type> paramtypes)
{
  ModuleBuilder dynamicMod = ... ; // supply this

  TypeBuilder tb = dynamicMod.DefineType("delegate-maker" + Guid.NewGuid(), 
      TypeAttributes.Public | TypeAttributes.Sealed, typeof(MulticastDelegate));

  tb.DefineConstructor(MethodAttributes.RTSpecialName | 
       MethodAttributes.SpecialName | MethodAttributes.Public |
       MethodAttributes.HideBySig, CallingConventions.Standard,
       new Type[] { typeof(object), typeof(IntPtr) }). 
       SetImplementationFlags(MethodImplAttributes.Runtime);

  var inv = tb.DefineMethod("Invoke", MethodAttributes.Public | 
       MethodAttributes.Virtual | MethodAttributes.NewSlot | 
       MethodAttributes.HideBySig, 
       CallingConventions.Standard ,returntype,null, 
       new Type[] 
       { 
          // this is the important bit
          typeof(System.Runtime.CompilerServices.CallConvCdecl)
       }, 
       paramtypes.ToArray(), null, null);

  inv.SetImplementationFlags(MethodImplAttributes.Runtime);

  var t = tb.CreateType();
  return t;
}

这篇关于从 C# 调用 C++ 函数 - 堆栈不平衡的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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