“P/Invoke entry points should exist” with what should be correct entry points stated

有些话、适合烂在心里 提交于 2020-01-04 02:41:13

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!