Search code examples
c#c++.netdllimportintptr

Can we replace all "int" parameter & return types with "IntPtr" in the DllImport method signature?


In my program, I have some DllImports since I want to call some native APIs. int type is used for the method parameters & returns types. It was working quite well until I ran my application on new Windows 2012 R2 Server (64 bit). The problem is fixed when I changed one of the ref parameter's type from int to IntPtr.

I know that IntPtr is used to represent a pointer or a handle. However, MSDN also says that IntPtr is "designed to be an integer" whose size is platform-specific. So if IntPtr is capable of handling the platform specific size of the integer, is it OK to replace all int parameters & return types with IntPtr?

I am using C# .NET 4.0.


Solution

  • No, you cannot blindly do this. 64-bit code still heavily uses 32-bit integral types, their "native integer" is still a 32-bit value. If you see an int or a long in the native code declaration (or an equivalent typedef alias) then you still use int in your pinvoke declaration.

    While that might not sound like a very sensible thing to do for a 64-bit compiler, there is a very good reason why they did not upgrade their native integer type. Modern processors are extraordinary fast but are limited by how fast they can address memory. Their execution engines run at gigahertz speeds but the memory bus is glacially slow. An electrical design problem related to distance, the further a signal has to travel the slower it needs to change state to still be recognized correctly at the other end of the wire. A problem solved partially by using caches, copies of memory that are located close to the execution engine. Those caches don't double in size. Using the caches effectively is very important to speed, so using 32-bit integral values where possible is important.

    Examples of native types that are IntPtr are any pointer type, size_t, XXX_PTR, WPARAM, LRESULT. The latter are typedefs, they can make it difficult to recognize the underlying type. When in doubt, write a little C program that uses sizeof so you know a fact.

    The formal definition is the data model used by the 64-bit native compiler. Microsoft compilers use LLP64.