Проблема в том, что на 64-битной Windows C long все еще 32-битная в отличие от Linux, где она 64-битная, и это вызывает некоторую боль.
Если вы не планируете поддерживать 64-битную Windows, это просто - вы можете сопоставить long с IntPtr в вашем определении DllImport. IntPtr является 32-битным на 32-битных окнах и Linux, что совпадает с длиной. Длинный в 64-битном Linux также является 64-битным, как и IntPtr, однако в Windows 64-битном, в то время как IntPtr в 64-битном является 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);
}
P.S .: Если вы не используете .NET 4, другой способ проверить, является ли вы 64-битным процессом, будет bool is64Bit = IntPtr.Size == 8