将指向数组的指针从C#传递到C DLL

将指向数组的指针从C#传递到C DLL,c#,arrays,pointers,marshalling,dllimport,C#,Arrays,Pointers,Marshalling,Dllimport,我有一个dll,它的参数是double*,例如xyz(double*a,double*b)。我使用这个DLL将两个双数组传递给函数xyz。问题是,当我使用a通过引用传递双数组时,数组正在更新,但当您在int中键入或从int中键入内容时,会发生值舍入的情况。您能否告诉我一种有效的方法,将此双数组发送到c dll并以十进制形式获得所需的结果。(更改DLL不是一个选项)。此外,我还尝试了Marshal,我不完全确定我是否做了正确的事情,但每当我将xyz的参数更改为xyz(IntPtr a,double

我有一个dll,它的参数是double*,例如xyz(double*a,double*b)。我使用这个DLL将两个双数组传递给函数xyz。问题是,当我使用a通过引用传递双数组时,数组正在更新,但当您在int中键入或从int中键入内容时,会发生值舍入的情况。您能否告诉我一种有效的方法,将此双数组发送到c dll并以十进制形式获得所需的结果。(更改DLL不是一个选项)。此外,我还尝试了Marshal,我不完全确定我是否做了正确的事情,但每当我将xyz的参数更改为xyz(IntPtr a,double*b)或用于获取AccessViolationException、内存损坏等信息时。

如果我理解正确,您正在将数组从C#传递到C(或C++)代码。将数组直接发送到类似
xyz(double*a,double*b)
的方法的问题在于,代码无法知道数组的大小。一旦C/C++代码试图访问超出数组边界的元素,就会出现访问冲突异常

有多种方法可以解决这一问题——使用C#中的SafeArray(已经包含size属性),将数组发送到具有大小的桥接方法,或者在结构中传递数据,如下所示:

internal struct ArraysStruct
{
    public int floatArraySize;
    public IntPtr floatArray;
    public int uintArraySize;
    public IntPtr uintArray; 
}
然后在C/C++端匹配如下内容:

typedef struct ArraysStruct
{
    size_t floatArraySize;
    float* floatArray;
    size_t uintArraySize;
    unsigned int* uintArray;
}

您需要先使用
Marshal.AllocHGlobal()
将数组分配到大小(在C#中),然后使用
Marshal.FreeHGlobal()

如果我理解正确,您正在将数组从C#传递到C(或C++)代码。将数组直接发送到类似
xyz(double*a,double*b)
的方法的问题在于,代码无法知道数组的大小。一旦C/C++代码试图访问超出数组边界的元素,就会出现访问冲突异常

有多种方法可以解决这一问题——使用C#中的SafeArray(已经包含size属性),将数组发送到具有大小的桥接方法,或者在结构中传递数据,如下所示:

internal struct ArraysStruct
{
    public int floatArraySize;
    public IntPtr floatArray;
    public int uintArraySize;
    public IntPtr uintArray; 
}
然后在C/C++端匹配如下内容:

typedef struct ArraysStruct
{
    size_t floatArraySize;
    float* floatArray;
    size_t uintArraySize;
    unsigned int* uintArray;
}
您需要先使用
Marshal.AllocHGlobal()
将数组分配到大小(以C#为单位),然后使用
Marshal.FreeHGlobal()

尝试以下操作:

            double[] a = { 1.23, 2.34, 5.45 };
            IntPtr aptr = Marshal.AllocHGlobal(a.Length * sizeof(double));
            Marshal.Copy(a, 0, aptr, a.Length);
            double[] b = { 1.23, 2.34, 5.45 };
            IntPtr bptr = Marshal.AllocHGlobal(b.Length * sizeof(double));
            Marshal.Copy(b, 0, bptr, b.Length);

            xyz(aptr, bptr)
请尝试以下操作:

            double[] a = { 1.23, 2.34, 5.45 };
            IntPtr aptr = Marshal.AllocHGlobal(a.Length * sizeof(double));
            Marshal.Copy(a, 0, aptr, a.Length);
            double[] b = { 1.23, 2.34, 5.45 };
            IntPtr bptr = Marshal.AllocHGlobal(b.Length * sizeof(double));
            Marshal.Copy(b, 0, bptr, b.Length);

            xyz(aptr, bptr)

没有必要这样做。将参数声明为
double[]
,然后简单地传递数组。封送拆收器将固定数组并传递其第一个元素的地址。这比分配和复制更有效。不需要这样做。将参数声明为
double[]
,然后简单地传递数组。封送拆收器将固定数组并传递其第一个元素的地址。这比分配和复制更有效。将参数声明为
double[]
并传递数组。很简单。您可能错误地使用了
ref double[]
,但我们无法知道,因为您没有显示代码。从您关于“舍入”和“小数”的评论来看,我想知道您的互操作是否真的没有问题,也许您的问题确实在这里得到了解决:将参数声明为
double[]
并传递数组。很简单。您可能错误地使用了
ref double[]
,但我们无法知道,因为您没有显示代码。从您关于“四舍五入”和“十进制”的评论来看,我想知道您的互操作是否真的没有问题,也许您的问题在这里得到了解决: