在 C# 中使用 p/invoke 调用创建结构体数组的 C 函数

问题描述 投票:0回答:1

我有一个 C 函数,可以创建一个结构数组:

struct Point {
    int x, y;
};

void GetPoints(Point points[], int* size) {
    size = 5;
    points = (Points*) malloc(sizeof(Point) * size);
    // ... fill in each structure with data
}

考虑到

points
的大小在调用函数之前未知,从 C# 调用此函数的正确方法是什么?

c# c pinvoke
1个回答
0
投票

该代码中有一些错误。

#1。如果要修改 Point 数组,则需要一个指针的指针(或

Point** points
),否则当您分配
points = something
时,您只是更改副本。

#2。当您乘以大小时,您需要取消引用指针,现在您正在乘以数组的内存地址。

void GetPoints(Point** points, int* size) {
    *size = 5;
    *points = (Point*) malloc(sizeof(Point) * (*size));
    ...
}

在 C# 方面,类似这样的东西应该可以工作:

[StructLayout(LayoutKind.Sequential)]
public struct Point {
    public int x, y;
}

public class NativeMethods {
    [DllImport("YourDllName", CallingConvention = CallingConvention.Cdecl)]
    public static extern void GetPoints(out IntPtr points, out int size);
}

class Program {
    static void Main() {
        IntPtr pointsPtr;
        int size;

        NativeMethods.GetPoints(out pointsPtr, out size);

        Point[] points = new Point[size];
        for (int i = 0; i < size; i++) {
            points[i] = Marshal.PtrToStructure<Point>(IntPtr.Add(pointsPtr, i * Marshal.SizeOf(typeof(Point))));
        }

        for (int i = 0; i < size; i++) {
            Console.WriteLine($"Point {i}: x={points[i].x}, y={points[i].y}");
        }

        // Free the unmanaged memory
        Marshal.FreeHGlobal(pointsPtr);
    }
}

https://learn.microsoft.com/en-us/dotnet/api/system.runtime.interopservices.marshal.ptrtostruct?view=net-8.0

© www.soinside.com 2019 - 2024. All rights reserved.