处理不同的非托管整数大小

发布于 2024-10-31 00:36:12 字数 702 浏览 1 评论 0原文

我有一个 C 库。它有许多函数调用,如下所示:

void init_foo( unsigned long x, unsigned long y );

库本身在运行时动态加载(而不是像插件)。标头在所有平台上都是一致的。

我的问题是,在 Windows 和 32 位 Linux 上,unsigned long 是 32 位,但在 64 位 Linux 上这是 64 位。

该库的各种实现都接受这一点,您需要为正确的目标平台构建 C 程序(如预期的那样)。

根据架构,我的互操作方法将需要是其中之一。

#if lin64
[DllImport("libfoo")]
public static void init_foo( Uint64 x, Uint64 y );
#else
[DllImport("libfoo")]
public static void init_foo( Uint32 x, Uint32 y );
#endif

我可以使用的 C# 类型在所有平台上都是固定大小的(因为它们应该是这样)。因此,我从 .Net/Mono 传递的托管 long 将始终是非托管 uint64_t

如何处理这种可变的整数大小,同时拥有一个可以在 .Net 或 mono 上以 32 位或 64 位模式运行的单个程序集?

I have a C library. It has many function calls like the following:

void init_foo( unsigned long x, unsigned long y );

The library itself is dynamically loaded at runtime (rather like a plugin). The headers are consistent across all platforms.

My problem is that on windows and 32bit linux, unsigned long is 32bits, yet on 64bit linux this is 64bits.

The various implementations of this library all accept this, you need to build your C program for the right target platform (as expected).

My interop method will need to be one of these depending on the architecture.

#if lin64
[DllImport("libfoo")]
public static void init_foo( Uint64 x, Uint64 y );
#else
[DllImport("libfoo")]
public static void init_foo( Uint32 x, Uint32 y );
#endif

The C# types I can use are fixed size on all platforms (as they should be). So my managed long passed from .Net/Mono will always be an unmanaged uint64_t.

How can I cope with this variable integer size yet have a single assembly that will run on .Net or mono in either 32bit or 64bit mode?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

如日中天 2024-11-07 00:36:12

问题是,在 64 位 Windows 上,C long 仍然是 32 位,而在 Linux 上是 64 位,这会带来一些麻烦。

如果您不打算支持 64 位 Windows,这很简单 - 您可以在 DllImport 定义中将 long 映射到 IntPtr。 IntPtr在32位windows和linux上都是32位的,和long是一样的。在 64 位 Linux 上,Long 也是 64 位,IntPtr 也是 64 位,但是在 Windows 64 位上,IntPtr 是 64 位,long 是 32 位。

如果你想支持 64 位 Windows,你可以同时定义两个签名 - 一个用于 64 位,一个用于 32 位,如下所示:

[DllImport("libfoo", EntryPoint="init_foo")]
public static void init_foo_64bit( Uint64 x, Uint64 y );

[DllImport("libfoo", EntryPoint="init_foo")]
public static void init_foo_32bit( Uint32 x, Uint32 y );

然后在你的代码中,你可以在运行时动态决定调用哪个签名,如下所示:

public void InvokeFoo(long x, long y)
{
    if (Environment.Is64BitProcess)
        return init_foo_64bit(x, y);
    return init_foo_32bit((int)x, (int)y);
}

PS:如果您不在 .NET 4 上,检查您是否是 64 位进程的另一种方法是 bool is64Bit = IntPtr.Size == 8

The problem is that on 64bit Windows C long is still 32bit unlike on Linux where it's 64bit and that causes a bit of a pain.

If you don't plan to support 64bit Windows it's easy - you can map the long to IntPtr in your DllImport definition. IntPtr is 32bit on both 32bit windows and linux, which is the same as long. Long on 64bit Linux is also 64bit and so is IntPtr, however on Windows 64bit while IntPtr is 64bit long is 32bit.

If you want to support 64bit Windows you can maybe define two signatures at the same time - one for 64bit and one for 32bit like that:

[DllImport("libfoo", EntryPoint="init_foo")]
public static void init_foo_64bit( Uint64 x, Uint64 y );

[DllImport("libfoo", EntryPoint="init_foo")]
public static void init_foo_32bit( Uint32 x, Uint32 y );

Then in your code you can dynamically decide at run-time which one to call like that:

public void InvokeFoo(long x, long y)
{
    if (Environment.Is64BitProcess)
        return init_foo_64bit(x, y);
    return init_foo_32bit((int)x, (int)y);
}

P.S: If you aren't on .NET 4 another way to check if you are a 64bit process will be bool is64Bit = IntPtr.Size == 8

暖心男生 2024-11-07 00:36:12

另一种可能性是编写另一个具有单个 API 的 C 库,该 API 在 .Net 平台之间不会有所不同,而是为每个平台提供正确的包装器库。

Another possibility would be to write another C library with a single API that does not vary between .Net platforms and instead ship the correct wrapper library for each.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文