Search code examples
c#pinvokedllimportunmanagedulong

Strange C# platform invoke / DLLImport behaviour


I have an unmanaged DLL I am referencing in my project using [DLLImport], but am receiving odd results when I match method signatures.

Here is an example signature from the DLL:

DLLEXPORT unsigned long OpenPort(unsigned long  ulPort,
                                     unsigned long  ulBaudRate,
                                     unsigned long  ulByteSize,
                                     unsigned long  ulPartity,
                                     unsigned long  ulStopBits,
                                     unsigned long  ulFlowControl)

And here is my C# code to import the function:

[DllImport("C:/my.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern uint OpenPort(ulong ulPort, ulong ulBaudRate,
    ulong ulByteSize, ulong ulParity, ulong ulStopBits, ulong ulFlowControl);

Notice I declare this with a return type of uint, as when I attempt to use ulong I get unexpected results (long numbers usually that look a bit like memory addresses).

However, the function works and returns expected results if I use a return type of int/uint. Can anyone shed any light on this behaviour for me?

Thanks.


Solution

  • I'm assuming that your target platform is Windows, based on the name of your library in the DllImport attribute. On Windows, the C++ long type (unsigned as well as signed, obviously) is 4 bytes wide, for both 32 and 64 bit. So, you need to declare your p/invoke using uint rather than ulong.

    The correct declaration is:

    [DllImport("C:/my.dll", CallingConvention = CallingConvention.Cdecl)]
    public static extern uint OpenPort(
        uint ulPort, 
        uint ulBaudRate,
        uint ulByteSize, 
        uint ulParity, 
        uint ulStopBits, 
        uint ulFlowControl
    );
    

    Now, if your target platform is other than Windows, then you'd need to know what unsigned long is on that platform to give specific advise.