Processing various unmanaged integer sizes

I have a C library. It has many function calls, such as:

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

The library itself is dynamically loaded at runtime (rather, like a plugin). Headings correspond to all platforms.

My problem is that on Windows and 32-bit Linux, the unsigned 32-bit is long, but on 64-bit Linux it is 64 bits.

Various implementations of this library accept all this; you need to create your own C-program for the correct target platform (as expected).

My interaction method should be one of them 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 that I can use are fixed size on all platforms (as it should be). That way my managed long passed from .Net / Mono will always be unmanaged uint64_t .

How can I handle this size of the integer value of a variable, but you have one assembly that will work on .Net or mono in 32-bit or 64-bit mode?

+8
c # integer mono unmanaged
source share
2 answers

The problem is that on 64-bit Windows C there is still 32-bit for a long time, unlike Linux, where it is 64-bit, and this causes a little pain.

If you do not plan to support 64-bit Windows, this is easy - you can match the long one with IntPtr in the definition of DllImport. IntPtr 32bit on both 32-bit windows and linux, which is just as long. Long on 64-bit Linux is also 64-bit, as well as IntPtr, however on Windows 64bit, while IntPtr is 64-bit 32-bit.

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

 [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 select at run time, which can be invoked as follows:

 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: If you are not using .NET 4, another way to check if you are a 64-bit process would be bool is64Bit = IntPtr.Size == 8

+4
source share

Another possibility would be to write another C library with one API that will not change between .Net platforms and instead send the correct wrapper library for each.

0
source share

All Articles