[英]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.