在 pinvoke 类/结构构造中使用元帅与不使用元帅
本文关键字:pinvoke 结构 | 更新日期: 2023-09-27 18:30:23
我有以下 c#/c 代码,我在 C dll 中做事。 我使用 pinvoke/marshal 作为黑魔法,使我能够在 dll 中动态分配/释放内容,而无需 c# 代码知道发生了什么不幸的事情。
在此代码段中,您将看到我正在使用 2 种不同的方法来分配/使用/释放双精度数组。 我的问题是,"元帅(非托管类型)..."行,因为两个咒语(即使用或不使用元帅声明)都可以正常工作? 我应该补充一点,我对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]);
}
这种
对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
函数是什么意思,但它根本没有意义,也不会编译。看起来您正在尝试将指针分配给一个毫无意义的双精度。