【问题标题】:How to convert PInvoke `<[In](),Out()> ByRef` to C#?如何将 PInvoke `<[In](),Out()> ByRef` 转换为 C#?
【发布时间】:2018-09-05 02:04:30
【问题描述】:

我有一个来自这个 VB.net 的函数需要导入到 C#。 我尝试了各种 VB.NET 到 C# 的转换器,但它不能与与此函数关联的导入 dll 正常工作。 任何人都知道如何将以下 VB 函数正确转换为 C#:

  <DllImport("E5KDAQ.dll")> _
  Public Function E5K_ReadDIStatus(ByVal id As Short,<[In](),Out()> ByRef chnval As Integer) As Short
  End Function

使用在线转换器,它提供以下内容: 转换有错误的c#

[DllImport("E5KDAQ.dll")]
public static extern short E5K_ReadDIStatus(short id, [In()] out int chnval);

【问题讨论】:

  • 试试public static extern short E5K_ReadDIStatus(short id, [In(), Out()] ref int chnval);
  • has error 请把错误放在文本而不是图片中。
  • 在 C# 中,out 用于仅用于输出的参数,而ref 用于用于提供输入和输出的参数。在 VB 中,ByRef 用于两者。这就是使用属性来限定ByRef 关键字的原因。这些属性清楚地表明chnval 参数将用于输入和输出,这意味着ref 必须在C# 中使用。因为ref 是明确的,您可能甚至不需要这些属性,但如果您确实包含它们,您显然需要两者。
  • 感谢 Ahmed Abdelhameed,您的解决方案有效

标签: c# vb.net pinvoke vb.net-to-c#


【解决方案1】:

来自官方文档:http://www.acceed.de/manuals/inlog/EDAM5000_Manual.pdf 有一个 C++ 定义,还有一些关于第二个参数是什么的文档,这正是您想要查看的内容:

VC++:(参见 E5KDAQ.h)

unsigned short E5K_ReadDIStatus (int id, unsigned long *Didata);

参数:

id:模块ID地址

Didata:指向一个 32 位缓冲区来存储 DI 状态

所以 C# 的定义应该是(C++ 中的longint 是 32 位的)

[DllImport("E5KDAQ")]
static extern ushort E5K_ReadDIStatus(int id, ref uint Didata)

【讨论】:

  • 第一个参数不是int16/short有什么原因吗?
  • @AhmedAbdelhameed - 在 C++ 中声明为 int
  • 哦,我的错。我不太了解 C++,出于某种原因,我读过键入为 "long in C++ is 32-bit" 的内容(没有 " 和 int" : D) 所以我假设 int 将是 16 位(例如 VB6)。
【解决方案2】:

你可以使用它。

public static extern short E5K_ReadDIStatus(short id, ref int[] chnval)

参考:Are P/Invoke [In, Out] attributes optional for marshaling arrays?

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-02-22
    • 1970-01-01
    • 2022-10-24
    • 1970-01-01
    相关资源
    最近更新 更多