-1

我有以下 c#/c 代码,我在 C dll 中做事。我正在使用 pinvoke/marshal 作为黑魔法,它使我能够在 dll 中动态分配/释放东西,而 C# 代码不知道发生了什么不愉快的事情。

在这个片段中,您将看到我使用 2 种不同的方式来分配/使用/释放一个双精度数组。我的问题是,“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]);
}
4

1 回答 1

-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;
}

这两个版本非常不同。

我还想知道您是否真的打算IntPtr[]在 C# 代码中使用。你也许真的想写double[]?所以,也许你实际上的意思是:

[StructLayout(LayoutKind.Sequential)]
public class row
{
    public int a;
    double[] b;
    double[] c; 
} 

在这种情况下,匹配的 C 结构将是:

struct row
{
    int a;
    double *b;
    double *c;
}

我不知道该fooe函数是什么意思,但它根本没有意义,也无法编译。看起来您正试图将一个指针分配给一个非常没有意义的双精度数。

于 2013-09-05T06:29:58.157 回答