c# - 编码结构数组以从 C# 调用非托管函数

标签 c# pinvoke marshalling

我必须从 C# 调用一个非托管函数,并且必须为其提供一个坐标数组( double )。这种情况下编码如何正确工作?

在非托管方面:

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

这个工作流程是否正确?

问候 汤姆托雷尔

最佳答案

首先在非托管方面,char* 是一个可修改的字符串。您应该在此处使用 const 来指示数据从调用方流向被调用方。对其他参数做同样的事情是有意义的:

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

现在所有数据的流动方式都清楚了。

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

您显示的结构声明完全匹配。关于这个主题没有更多要说的了。

您还可以使用默认编码来简化 p/invoke。我会这样写:

[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);

关于c# - 编码结构数组以从 C# 调用非托管函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24905466/

相关文章:

c# - 为什么我的身份数据库表没有迁移到 Azure?

c# - P/Invoke Interop Assistant - 是否像导入 dll 的 header 一样简单?

c# - P/Invoke 到 Mono 上动态加载的库

c# - 编码——它是什么以及我们为什么需要它?

java - 使用 JAXB 编码(marshal)时出现内存不足错误

c# - 如何检测 .Net 中(路由器/网关的)公共(public) IP 地址的变化?

c# - 显示 HH :mm:ss in DateTime x axis in Chart C#

c# - 根据值更改 Silverlight4 中文本 block 的前景色

c# - 如何使用带有 C# 的 DllImport 在 OSX 上获取剪贴板文本?

python - 有效地将扁平字符串解析为嵌套字典