【问题标题】:How to pass an unsigned long to a Linux shared library using P/Invoke如何使用 P/Invoke 将 unsigned long 传递给 Linux 共享库
【发布时间】:2009-11-17 22:21:47
【问题描述】:

我在 Mono 中使用 C#,并尝试使用 pinvoke 调用 Linux 共享库。

c#调用定义为:

   [DllImport("libaiousb")]
   extern static ulong AIOUSB_Init();

Linux函数定义如下:

  unsigned long AIOUSB_Init() {
       return(0);
  }

Linux代码的编译命令是:

gcc -ggdb -std=gnu99 -D_GNU_SOURCE -c -Wall -pthread -fPIC
      -I/usr/include/libusb-1.0  AIOUSB_Core.c -o AIOUSB_Core.dbg.o

我可以调用该函数,但返回结果很糟糕。它应该是 0,但我得到了一些巨大的错误数字。

我已经在函数值返回之前将printf's放在Linux代码中并且它是正确的。

我注意到有点奇怪的一点是 printf 应该在函数返回之前发生。但是,我看到函数返回到 C#,然后 c# 打印返回结果,最后显示 printf 结果。

【问题讨论】:

    标签: c# mono pinvoke


    【解决方案1】:

    来自here

    无符号长整数可以保存0ULONG_MAX 之间的所有值。 ULONG_MAX 必须至少为 4294967295。 long 类型必须至少包含 32 位才能保存所需的值范围。

    因此,C unsigned long 通常被转换为 .NET UInt32

    [DllImport("libaiousb")]
    extern static uint AIOUSB_Init();
    

    【讨论】:

    • 除非你在 64bit mono + linux 上运行它,那么 C unsigned long 将是 64bits。
    【解决方案2】:

    您可能在 C unsigned long 为 32 位的系统上运行它。 C# unsigned long 是 64 位。如果要确保返回值是 64 位无符号长整数,请包含 stdint.h 并从 AIOUSB_Init() 返回 uint64_t

    【讨论】:

    • 你说的太对了!非常感谢你!你不知道我在这件事上打了多久。我认为所有当前的奔腾处理器都使用 32 位字长,所以 unsigned long 应该是 64 位?我会寻找一种安全的方式使用贝宝向您发送我的感谢信!
    • 无符号长整型在 64 位平台(和 64 位操作系统下)只有 64 位,否则为 32 位。
    • 欲了解更多详情,请参阅我的回答:stackoverflow.com/questions/1753413/…
    • 仅供参考 unsigned long 在 64 位 Linux 上是 64 位,但在 Windows 上是 32 位。
    猜你喜欢
    • 2018-10-15
    • 2020-11-14
    • 1970-01-01
    • 1970-01-01
    • 2013-03-04
    • 2010-11-06
    • 1970-01-01
    • 2012-09-12
    相关资源
    最近更新 更多