我有以下c#/ c代码,我在C dll中做的事情。我使用pinvoke / marshal作为黑魔法,使我能够在dll中动态分配/释放内容,而不需要c#代码知道任何不正常的事情。
在这个片段中,您将看到我使用两种不同的方式来分配/使用/释放双打数组。我的问题是,“MarshalAs(UnmanagedType ...”行)是做什么的,因为两个咒语(即使用或不使用MarshalAs语句)都能正常工作?我应该补充一点,我对C的理解很差,甚至更少理解C#,我理解整个pinvoke / marshal以及我理解的超对称量子力学。
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public class row
{
public int a;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 12)]
IntPtr[] b;
IntPtr [] c;
}
// c code
struct row
{
int a;
double *b;
double *c;
}
void fooe(void)
{
row.b[4] = (double *) malloc(54000);
row.c[4] = (double *) malloc(54000);
free(row.b[4]);
free(row.c[4]);
}
答案 0 :(得分:-1)
ByValArray
的这种特殊用法改变了一切。
首先,让我们考虑一下不ByValArray
的情况。这里将数组编组为指向第一个元素的指针。匹配的C结构是
struct row
{
int a;
void* *b; // more likely you would use a typed pointer
void* *c;
}
否则您使用ByValArray
的情况。这里的数组是内联编组的,等效的C结构是:
struct row
{
int a;
void* b[12];
void* *c;
}
这两个版本非常不同。
我也想知道你是否真的打算在C#代码中使用IntPtr[]
。您是否真的想写double[]
?所以,也许你的意思是:
[StructLayout(LayoutKind.Sequential)]
public class row
{
public int a;
double[] b;
double[] c;
}
在这种情况下,匹配的C结构将是:
struct row
{
int a;
double *b;
double *c;
}
我不知道fooe
函数的含义是什么,但根本没有意义,也没有编译。看起来你正在尝试将指针指向一个毫无意义的双精度。