编组一个结构数组来调用c#中的非托管函数

本文关键字:调用 函数 数组 结构 一个 | 更新日期: 2023-09-27 18:14:33

我必须从c#调用一个非托管函数,并且必须提供一个坐标数组(双精度)给它。在这种情况下,编组如何正确地工作?

非托管端:

typedef struct dPoint3dTag
{
  double x, y, z;
} dPoint3d;
void UnmanagedModifyGeometry(char *strFeaId, dPoint3d *pnts, int iNumPnts);

我在托管端为DPoint3d定义了一个托管结构:

[StructLayout(LayoutKind.Sequential)]
public struct DPoint3d
{
// Constructor
public DPoint3d(double x, double y, double z)
{
this.x = x;
this.y = y;
this.z = z;
}
public double x, y, z;
}

我试图以这种方式从c#调用非托管函数:

// Import of the unmanaged function
[DllImport("Unmanaged.dll")]
public static extern void UnmanagedModifyGeometry([MarshalAs(UnmanagedType.LPStr)] string strFeaId, DPoint3d[] pnts, int iNumPnts);
// Using the unmanaged function from C#
// Allocating points
DPoint3d[] pnts = new DPoint3d[iPntCnt];
String strFeaId = "4711";
// After filling in the points call the unmanaged function
UnmanagedModifyGeometry(strFeaId, pnts, iPntCnt);

这个工作流程正确吗?

的问候tomtorell

编组一个结构数组来调用c#中的非托管函数

首先,在非托管端,char*是一个可修改的字符串。您应该在这里使用const来指示数据从调用方流向被调用方。对于其他参数也可以这样做:

void UnmanagedModifyGeometry(
    const char *strFeaId, 
    const dPoint3d *pnts, 
    const int iNumPnts
);

现在所有人都清楚了数据是如何流动的。

在托管端,声明有一个明显的问题,即您没有指定调用约定。默认值是stdcall,但您的非托管代码将是cdecl,假设问题中的声明是准确的。

所显示的结构声明完全匹配。关于那个问题没有什么可说的了。

你也可以使用默认的封送来简化p/调用。我会这样写:

[DllImport("Unmanaged.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern void UnmanagedModifyGeometry(
    string strFeaId, 
    [In] DPoint3d[] pnts, 
    int iNumPnts
);

然后这样命名:

DPoint3d[] pnts = new DPoint3d[...]; // supply appropriate value for array length
// populate pnts
UnmanagedModifyGeometry("4711", pnts, pnts.Length);