繁体   English   中英

从C ++ dll使用__declspec(dllexport)签名声明以在C#中调用时出现问题

[英]Issue using __declspec(dllexport) signature declaration from C++ dll to call in C#

我正在尝试调用在C ++ dll中声明为__declspec(dllexport)的方法以在C#中使用,但是我不知道如何从C ++返回字符串值以及如何在C#中使用DllImport声明签名。

C ++代码“VNVAPI.dll”

  __declspec(dllexport) char * GetGpuName(int phyGPUid)
  {
      CNvidia * pInstance = CNvidia::GetInstance();
      char  szName[512]={0};
      pInstance->GetGpuName(phyGPUid,szName,512);
      return szName;
  }

C#方法签名:

[DllImport("VNVAPI.dll")]
   public static extern  char GetGpuName(int phyGPUid);

生成错误:

对PInvoke函数'Core!Core.Hardware.IO.NVAPI :: GetGpuName'的调用已使堆栈不平衡。 这很可能是因为托管PInvoke签名与非托管目标签名不匹配。 检查PInvoke签名的调用约定和参数是否与目标非托管签名匹配。

谢谢。

正如其他人指出的那样,您需要在P / Invoke中指定C调用约定,并在托管端使用字符串来编组以null结尾的char *。

但是,您应该重新调整C ++例程以将char *与缓冲区长度参数一起作为输入参数。 然后,您可以在本机代码中写入此缓冲区。 这避免了当前的问题,即您当前具有代码的数据是从堆栈中返回的,而堆栈当然会在函数返回时解开。

使用静态的建议将使该内存成为全局内存,从而避免堆栈展开问题,但以线程安全为代价。 是的,它可能适用于此用例,但是这是一个坏习惯。

错误消息可能会令人困惑。

没有详细说明,试试这个:

static char  szName[512]={0};

如果仍然出现错误,则需要在DllImport属性中指定调用约定。

编辑:

还为C#方法声明创建返回类型string

错误消息建议检查调用约定。 我怀疑该函数正在使用C调用约定,这将解释不平衡堆栈。 我建议您在DllImport属性中指定调用约定(如@leppi建议的那样)。 像这样:

[DllImport("VNVAPI.dll", CallingConvention=CallingConvention.Cdecl)]

根据Strings样本 ,返回值应为string

static extern string GetGpuName(int phyGPUid);

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM