【发布时间】:2021-07-18 11:58:11
【问题描述】:
我有下面的 C++ dll
函数原型和结构定义
extern "C" int __declspec(dllexport) DoOPeration(DataStruct *&, DataStructInfo **&);
typedef struct
{
int count;
float CountData;
bool flg;
BYTE* data;
char info[100];
}DataStruct;
typedef struct
{
int count;
bool flg;
BYTE* data;
}DataStructInfo;
DoOPeration函数的实现如下
int __declspec(dllexport) ImageAnalyze(DataStruct *&all, DataStructInfo **&part)
{
int ret = 0;
try
{
if(all->count == 0)
return(ERR_PARAMERROR);
for(cnt = 0 ; cnt < all->count ; cnt++)
{
if(part[cnt]->data== NULL)
return(ERR_NO_IMAGE);
}
}
catch(int err)
{
return(err);
}
catch(...)
{
return(-2);
}
return(ret);
}
与上面对应,我添加了 C# 端代码,如下所示
DLL 导入、结构(类)定义
[DllImport(@"C:\TestDll.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern int DoOperation(ref DataStruct all, ref DataStructInfo[] part);
[StructLayout(LayoutKind.Sequential)]
public class DataStruct
{
int count = 0;
float CountData = 0;
bool flg = 0;
byte[] data = null;
string info = 0;
}
[StructLayout(LayoutKind.Sequential)]
public class DataStructInfo
{
int count = 0;
bool flg = 0;
byte[] data;
}
// DoOperation function calling
DataStruct alls = new DataStruct(); // set all required parameter
DataStructInfo[] part= new DataStructInfo[3]; // set all required parameter
int ret = DoOperation(ref alls, ref part);
从c#代码调用C++ dll函数后,我观察到了c++ dll中函数参数的值。
- 对于参数 [alls] 值正确传递
- 对于参数 [part] 值未正确传递(显示一些垃圾值)
请让我知道有关从 c# 代码传递第二个参数即 (**&) 的信息。
如果我犯了任何其他错误,请告诉我,以便我更正。
注意:我无法更改 C++ dll 代码
【问题讨论】:
-
您必须在此处进行一些手动编组,因为 C++ 的设计不正确。如果可以,第一步是更改 C++。如果你不能,那么你需要了解
&的含义。 -
c#中new DataStructInfo[3]只为三个结构分配内存,不做"new DataStructInfo()"三次
-
您最好的选择可能是在您的工具链上自己创建一个(虚拟)dll 来观察您的编译器的作用。有时 & 被实现为跨 dll 行的额外 * 。基本上你需要让你的身边有正确的指针深度。第一步是弄清楚如何改变它(在显式 * 中工作)。其次是尝试一些有根据的猜测(绝对不会使用比符号更多的层)。
标签: c# c++ dllimport dllexport