How to pass an unsigned long to a Linux shared library using P/Invoke
I am using C# in Mono and I'm trying to use pinvoke to call a Linux shared library.
The c# call is defined as:
[DllImport("libaiousb")]
extern static ulong AIOUSB_Init();
The Linux function is defined as follows:
unsigned long AIOUSB_Init() {
return(0);
}
The compile command for the Linux code is:
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
I can call the function ok but the return result is bonkers. It should be 0 but I'm getting some huge mangled number.
I've put printf's in the Linux code just before the function value is returned and it is correct.
One thing I have noticed that is a little weird is that the printf should occur before the function returns. However, I see the function return to C# and then the c# prints the return result and finally the p开发者_StackOverflowrintf result is displayed.
From here:
An unsigned long can hold all the values between
0
andULONG_MAX
inclusive.ULONG_MAX
must be at least4294967295
. The long types must contain at least 32 bits to hold the required range of values.
For this reason a C unsigned long
is usually translated to a .NET UInt32
:
[DllImport("libaiousb")]
extern static uint AIOUSB_Init();
You're probably running that on a system where C unsigned long is 32-bits. C# unsigned long is 64 bits. If you want to make sure the return value is a 64-bits unsigned long, include stdint.h
and return an uint64_t
from AIOUSB_Init().
精彩评论