Search code examples
c#pinvoke

Managed Type equivalent of [MarshalAs(UnmanagedType.I8)]


I have inherited a dll written in C that I access from a windows application (Framework 2.0) in C#. Recently some machines have been upgraded to 64-bit Windows 7, and the dll is no longer returning the correct values on those machines. I believe this is because the C function has parameter types that are expected to be 64-bit.

Here's the signature of the C function

int doFlightCalc_S(double LatA, 
                   double LonA, 
                   double LatB, 
                   double LonB, 
                   int month, 
                   int aircraftCd, 
                   int nbrPsgrs, 
                   int taxiInTm, 
                   int taxiOutTm, 
                   int fuelStopTime, 
                   int *results)

Here's the definition that accesses the function from C#

[DllImport("doFlightCalc.dll", CallingConvention = CallingConvention.Cdecl)]
        private static extern int doFlightCalc_S(
             [MarshalAs(UnmanagedType.R8)] double latA,
             [MarshalAs(UnmanagedType.R8)] double lonA,
             [MarshalAs(UnmanagedType.R8)] double latB,
             [MarshalAs(UnmanagedType.R8)] double lonB,
             [MarshalAs(UnmanagedType.I4)] int month,
             [MarshalAs(UnmanagedType.I4)] int aircraftCd,
             [MarshalAs(UnmanagedType.I4)] int nbrPsgrs,
             [MarshalAs(UnmanagedType.I4)] int taxiInTm,
             [MarshalAs(UnmanagedType.I4)] int taxiOutTm,
             [MarshalAs(UnmanagedType.I4)] int fuelStopTime,
            [MarshalAs(UnmanagedType.LPArray)] [Out] int[] results);

If I were to compile the C dll as a 64-bit dll while leaving the function as is, what changes would I need to make to the function in C#?

I would assume that I have to change the I4s to I8s but what type would I replace the int and double with? Would the following :

             [MarshalAs(UnmanagedType.R8)] double lonB,
             [MarshalAs(UnmanagedType.I4)] int month,

be changed to:

             [MarshalAs(UnmanagedType.R8)] (what would go here?) lonB,
             [MarshalAs(UnmanagedType.I8)] long (is long correct here?) month,

Or am I barking up the wrong tree?


Solution

  • You don't need to make any changes at all when you compile for 64 bit. The C and C# versions match each other on both 32 and 64 bit.

    You seem to think that C int is 8 bytes wide in 64 bit code on Windows. It is not. It is 4 bytes wide.

    You can remove all the MarshalAs attributes since they merely re-state the default marshalling.

    It seems highly unlikely that the switch from 32 bit OS to 64 bit OS is really the cause of the discrepancy.