Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/289.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 处理不同的非托管整数大小_C#_.net_Mono_Integer_Unmanaged - Fatal编程技术网

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

C# 处理不同的非托管整数大小,c#,.net,mono,integer,unmanaged,C#,.net,Mono,Integer,Unmanaged,我有一个C库。它有许多函数调用,如下所示: void init_foo( unsigned long x, unsigned long y ); 库本身是在运行时动态加载的(就像插件一样)。标题在所有平台上都是一致的 我的问题是,在windows和32位linux上,无符号长是32位,而在64位linux上是64位 这个库的各种实现都接受这一点,您需要为正确的目标平台构建C程序(如预期的那样) 根据体系结构的不同,我的互操作方法需要是其中之一 #if lin64 [DllImport("lib

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

void init_foo( unsigned long x, unsigned long y );
库本身是在运行时动态加载的(就像插件一样)。标题在所有平台上都是一致的

我的问题是,在windows和32位linux上,无符号长是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\u t


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

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

如果您不打算支持64位Windows,这很容易-您可以在DllImport定义中将long映射到IntPtr。IntPtr在32位windows和linux上都是32位的,与long相同。64位Linux上的Long也是64位的,IntPtr也是64位的,然而在Windows上,64位的IntPtr是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);
}
然后在代码中,您可以在运行时动态地决定调用哪一个:

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

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

另一种可能是使用单个API编写另一个C库,该API在.NET平台之间不存在差异,而是为每个平台提供正确的包装器库。

IanNorton:“我的问题是,在windows和32位linux上,无符号长是32位,而在64位linux上是64位。”“真的吗?我以为长的总是64位,因为整型是32位。。。您可以为64位版本发布一个单独的版本,否则我不知道。@Fox先生,是的,我可以,我想可能可以。为什么要使用long?为什么不使用int呢?非常感谢,这看起来是我最喜欢的函数调用,我也有一个包含long的结构的问题。我将继续寻找更多答案。定义两个结构和两个签名,其中任何一个都可以。在代码中使用64位结构,因为它具有更高的精度。在invokeMhod if 32位中,通过将long强制转换为int,将64位结构复制到32位结构。