问题
I'm getting this warning from the Code Analysis tool in Visual Studio 2012. The code looks like this:
using System;
using System.Runtime.InteropServices;
namespace MyProgramNamespace
{
class NativeMethods
{
[DllImport("user32.dll", EntryPoint = "GetWindowLongPtr")]
public static extern IntPtr GetWindowLongPtr(IntPtr handle, int flag);
[DllImport("user32.dll", EntryPoint = "SetWindowLongPtr")]
public static extern IntPtr SetWindowLongPtr(IntPtr handle, int flag, IntPtr ownerHandle);
}
}
I'm compiling for x64 only so I'm not concerned with using the old GetWindowLong and SetWindowLong. These entry point names are correct as far as I can tell.
Edit: SOLVED. Turns out the problem is that Visual Studio itself (and therefore the Code Analysis tool) are 32bit. When the code analysis tool checks user32.dll to see if those functions are there, it checks the 32bit version of user32.dll (in C:/Windows/SysWOW64/) instead of the one that the program will actually use (the 64bit version in C:/Windows/System32), and these functions only exist in the 64bit version (32bit version uses GetWindowLong/SetWindowLong instead of GetWindowLongPtr/SetWindowLongPtr (notice the PTR part)).
回答1:
The reason they don't work is that by specifying EntryPoint =
in the DllImport attribute, you are telling the Marshaller, "This is the exact function I want you to call".
There is no function called GetWindowLongPtr
in user32.dll. There is GetWindowLongPtrA
and GetWindowLongPtrW
.
When you leave out the EntryPoint=
, the Marshaller will call one or the other based on the running OS.
So either leave it out, or specify the A or W versions. If you specify A or W, you will also want to specify CharSet=CharSet.Ansi
for the A version or CharSet=CharSet.Unicode
for the W version.
回答2:
(This answer also posted in an edit at the bottom of the original question, to help people find it quick and easy)
Turns out the problem is that Visual Studio itself (and therefore the Code Analysis tool) are 32bit. When the code analysis tool checks user32.dll to see if those functions are there, it checks the 32bit version of user32.dll (in C:/Windows/SysWOW64/) instead of the one that the program will actually use (the 64bit version in C:/Windows/System32), and these functions only exist in the 64bit version (32bit version uses GetWindowLong/SetWindowLong instead of GetWindowLongPtr/SetWindowLongPtr (notice the PTR part)).
回答3:
Try the following:
[DllImport("user32.dll", EntryPoint = "GetWindowLongPtrW")]
public static extern IntPtr GetWindowLongPtr(IntPtr handle, int flag);
[DllImport("user32.dll", EntryPoint = "SetWindowLongPtrW")]
public static extern IntPtr SetWindowLongPtr(IntPtr handle, int flag, IntPtr ownerHandle);
来源:https://stackoverflow.com/questions/13147597/p-invoke-entry-points-should-exist-with-what-should-be-correct-entry-points-st