Does P/Invoke on 64-bit windows require different

2019-02-13 12:12发布

问题:

When I create a signature that refers to user32.dll for example should I be building this with user64.dll if the target is a 64-bit computer?

[DllImport("user32.dll", CharSet = CharSet.Auto)]
public static extern bool ChangeClipboardChain(
    IntPtr hWndRemove,
    IntPtr hWndNewNext);

Currently this isn't a problem as I'm targeting only 32-bit due to a library from a vendor (Progress OpenEdge) which only provide 32-bit libraries to access their database.

I don't currently have a 64-bit windows computer to see if this is the case.

回答1:

Despite the naming convention, user32.dll (and other 32... dlls) are actually 64 bit on 64 bit machines. These are the historical names for the dlls, and have been kept that way regardless of the changes to the underlying architecture. Have a read of this page to get more details.



回答2:

You should not need to change the signature/name of the DLL that you link to when calling in to USER32.DLL functions.

Despite the naming convention, on a 64-bit Windows machine, the USER32.DLL file that sits in [Windows]\System32 is actually a 64-bit DLL. The real 32-bit version of USER32.DLL actually sits in a folder called [Windows]\SysWow64.

Please see this question for further info.

The one thing you'll probably need to be most careful of is the datatypes that you pass in as parameters to the various Windows API functions. For example, the "SendMessage" function within USER32.DLL has a specific requirement with at least one of it's parameters (according to the page on P/Invoke).

It's signature is:

[DllImport("user32.dll", CharSet = CharSet.Auto)]
static extern IntPtr SendMessage(IntPtr hWnd, UInt32 Msg, IntPtr wParam, IntPtr lParam);

and notes 2 & 3 below clearly state:

2) NEVER use "int" or "integer" as lParam. Your code WILL crash on 64-bit windows. ONLY use IntPtr, a "ref" structure, or an "out" structure.

3) NEVER use "bool", "int", or "integer" as the return value. Your core WILL crash on 64-bit windows. ONLY use IntPtr. It's not safe to use bool - pInvoke cannot marshal an IntPtr to a boolean.

This "caveat" appears to be specific to this particular function (SendMessage), although it's something I would pay particular attention to when calling into any Windows API functions.



标签: c# 64bit pinvoke