如何在 C# 中将 DLLImport 与结构一起用作参数?

Posted

技术标签:

【中文标题】如何在 C# 中将 DLLImport 与结构一起用作参数?【英文标题】:How do I use DLLImport with structs as parameters in C#? 【发布时间】:2009-03-23 18:47:01 【问题描述】:

我可以找到使用 DLLImport 从 C# 调用 C++ 代码的所有示例来回传递整数。我可以让这些例子工作得很好。我需要调用的方法将两个结构体作为其导入参数,我不太清楚如何使其工作。

这是我必须处理的:

我拥有 C++ 代码,因此我可以对其进行任何我需要的更改/添加。

第三方应用程序将在启动时加载我的 DLL,并期望 DLLExport 以某种方式定义,因此我无法真正更改导出的方法签名。

我正在构建的 C# 应用程序将用作包装器,因此我可以将此 C++ 部分集成到我们的其他一些应用程序中,这些应用程序都是用 C# 编写的。

我需要调用的 C++ 方法签名是这样的

DllExport int Calculate (const MathInputStuctType *input, 
    MathOutputStructType *output, void **formulaStorage)

而MathInputStructType定义如下

typedef struct MathInputStuctTypeS 
    int             _setData;
    double              _data[(int) FieldSize];
    int             _setTdData;
 MathInputStuctType;

【问题讨论】:

【参考方案1】:

MSDN 主题Passing Structures 很好地介绍了将结构传递给非托管代码。您还需要查看Marshaling Data with Platform Invoke 和Marshaling Arrays of Types。

【讨论】:

非常感谢。这给了我足够的理解来让代码正常工作。【参考方案2】:

根据您发布的声明,您的 C# 代码将如下所示:

[DllImport("mydll.dll")]
static extern int Calculate(ref MathInputStructType input,
    ref MathOutputStructType output, ref IntPtr formulaStorage);

根据 C++ 中 MathInputStructType 和 MathOutputStructType 的结构,您还必须对这些结构声明进行属性化,以便它们正确编组。

【讨论】:

缺少函数名顺便说一句:) “您还必须为这些结构声明赋予属性,以便它们正确编组。”对,这是我不太明白的部分。我将结构添加到我的问题中。【参考方案3】:

对于结构:

struct MathInputStuctType 

    int       _setData;
    [MarshalAs(UnmanagedType.ByValArray, SizeConst = FieldSize)]
    double[]  _data;
    int       _setTdData;

【讨论】:

我不确定它是否是 100% 必要的,但您应该将 _data 字段的 ArraySubType 设置为 UnmanagedType.R8。 应该可以推断出来(我认为,作为编组器非常好)。【参考方案4】:

您可能想在 CodePlex 上查看此项目,http://www.codeplex.com/clrinterop/Release/ProjectReleases.aspx?ReleaseId=14120。它应该可以帮助您正确编组结构。

【讨论】:

这看起来很酷,但无论我选择什么 DLL,它总是告诉我需要一个清单。如果它有效的话,它看起来像一个很酷的工具。 不知道有这么严格,抱歉。 您可以使用 SigImp Translate Snippet 选项卡查看如何在 C# 中定义特定 C++ 代码,而不是尝试打开 DLL。

以上是关于如何在 C# 中将 DLLImport 与结构一起用作参数?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 C# 中将 lambda 与方法一起使用?

如何在 C# 中将 HttpClient PostAsync() 与线程池一起使用?

如何在 C# 中将 Byte* 从 C++ 转换为 Byte[]

C# 包装类和来自 c++ 的 dllimport

在 C# 中将 `is` 运算符与泛型一起使用

c#调用c++写的dll,用dllimport后说啥 找不到指定模块。这个问题你是怎么解决的