“P / Invoke入口点应该存在”,应该指出正确的入口点

时间:2012-10-30 21:07:40

标签: c# interop pinvoke analysis

我从Visual Studio 2012中的代码分析工具收到此警告。代码如下所示:

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);
    }
}

我正在为x64编译,所以我不关心使用旧的GetWindowLong和SetWindowLong。据我所知,这些入口点名称是正确的。

编辑:已解决。 原来问题是Visual Studio本身(因此代码分析工具)是32位。当代码分析工具检查user32.dll以查看是否存在这些函数时,它会检查32位版本的user32.dll(在C:/ Windows / SysWOW64 /中)而不是程序实际使用的版本(64位版本)在C:/ Windows / System32中,这些函数只存在于64位版本中(32位版本使用GetWindowLong / SetWindowLong而不是GetWindowLongPtr / SetWindowLongPtr(注意PTR部分))。

3 个答案:

答案 0 :(得分:1)

他们不工作的原因是,通过在DllImport属性中指定EntryPoint =,您告诉Marshaller,“这是我希望您调用的确切函数”。

user32.dll中没有名为GetWindowLongPtr的函数。有GetWindowLongPtrAGetWindowLongPtrW

当您遗漏EntryPoint=时,Marshaller将根据正在运行的操作系统调用其中一个。

因此要么将其保留,要么指定A或W版本。如果您指定A或W,则还需要为A版本指定CharSet=CharSet.Ansi或为W版本指定CharSet=CharSet.Unicode

答案 1 :(得分:1)

(这个答案也发布在原始问题底部的编辑中,以帮助人们快速轻松地找到它)

原来问题是Visual Studio本身(因此代码分析工具)是32位。当代码分析工具检查user32.dll以查看是否存在这些函数时,它会检查32位版本的user32.dll(在C:/ Windows / SysWOW64 /中)而不是程序实际使用的版本(64位版本)在C:/ Windows / System32中,这些函数只存在于64位版本中(32位版本使用GetWindowLong / SetWindowLong而不是GetWindowLongPtr / SetWindowLongPtr(注意PTR部分))。

答案 2 :(得分:0)

尝试以下方法:

    [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);