Входните точки на P/Invoke трябва да съществуват с посочените правилни входни точки

Получавам това предупреждение от инструмента за анализ на код във 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 частта)).


person Steve Niles    schedule 30.10.2012    source източник
comment
Това е предположение, но може би инструментът за анализ на кода проверява само 32-битовата версия на user32.dll. Get/SetWindowLongPtr не съществува в 32-битовата версия на user32.dll. Ако самият инструмент за анализ на код е 32-битов, това може да е причината.   -  person shf301    schedule 31.10.2012
comment
Освен това, ако коментирам долните 2 реда (за SetWindowLongPtr), всички предупреждения изчезват. И все пак с тези некоментирани редове и двата метода Get и Set дават предупреждението. Ако коментирам само горните 2 реда (Get), Set все още дава предупреждение   -  person Steve Niles    schedule 31.10.2012
comment
@Jargon Бих публикувал решението като отговор и бих го маркирал, тъй като нито един от дадените отговори не беше правилен (включително моя).   -  person Tergiver    schedule 31.10.2012


Отговори (3)


Причината да не работят е, че като посочите EntryPoint = в атрибута DllImport, вие казвате на Marshaller: „Това е точната функция, която искам да извикате“.

Няма функция, наречена GetWindowLongPtr в user32.dll. Има GetWindowLongPtrA и GetWindowLongPtrW.

Когато оставите EntryPoint=, Marshaller ще извика едното или другото въз основа на работещата ОС.

Така че или го оставете, или посочете A или W версиите. Ако посочите A или W, ще искате също да посочите CharSet=CharSet.Ansi за версия A или CharSet=CharSet.Unicode за версия W.

person Tergiver    schedule 30.10.2012
comment
Опитах да премахна EntryPoint, не го коригира и също опитах да добавя CharSet (пробвах A с Ansi и W с Unicode), нито едно не накара предупреждението да изчезне - person Steve Niles; 31.10.2012
comment
@Jargon Предупреждение? Откъде идва това предупреждение? Със сигурност не компилаторът. Използвате ли някакъв инструмент за проверка на код? - person Tergiver; 31.10.2012
comment
@Jargon След това го потърсих в Google (msdn.microsoft.com/en-us/library /ms182208.aspx). Това е от FxCop. Просто деактивирайте предупреждението и проверете дали обаждането е успешно по време на изпълнение. - person Tergiver; 31.10.2012
comment
Да, споменах в първия ред на публикацията си, че това е инструментът за анализ на код във Visual Studio 2012 (който преди беше FxCop в по-старите версии). Бих могъл да потисна предупреждението, но бих предпочел да знам какво го причинява, за да съм сигурен, че правя взаимодействието правилно. - person Steve Niles; 31.10.2012
comment
@Jargon Според връзката, която дадох, това е причинено, защото инструментът за проверка не може да намери DLL. Защо не може да намери системна DLL, не знам, но казва, че търси само в същата директория като изпълнимия файл. - person Tergiver; 31.10.2012
comment
Това трябва да е. Копирах user32.dll от папката System32 и предупрежденията изчезнаха. Ако копирам user32.dll от SysWOW64 (32-битовата версия), предупрежденията остават. Предполагам, че това е, което получавам за писане на x64 код в x86 IDE - person Steve Niles; 31.10.2012

(Този отговор също е публикуван в редакция в долната част на оригиналния въпрос, за да помогне на хората да го намерят бързо и лесно)

Оказва се, че проблемът е, че самото Visual Studio (и следователно инструментът за анализ на код) са 32-битови. Когато инструментът за анализ на код проверява user32.dll, за да види дали тези функции са там, той проверява 32-битовата версия на user32.dll (в C:/Windows/SysWOW64/) вместо тази, която програмата действително ще използва (64-битовата версия в C:/Windows/System32) и тези функции съществуват само в 64-битовата версия (32-битовата версия използва GetWindowLong/SetWindowLong вместо GetWindowLongPtr/SetWindowLongPtr (забележете PTR частта)).

person Steve Niles    schedule 21.11.2012

Опитайте следното:

    [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);
person Jigsore    schedule 30.10.2012
comment

Имам голямо сървърно приложение, където повечето неща са базирани на асинхронен javascript.

Използвам селен, за да го тествам и имам концептуален въпрос: Колко силни трябва да бъдат твърденията в предварителните условия на определен тест?

Например: ако трябва да направя XX и YY, за да тествам ZZ, трябва ли да твърдя XX и YY, дори да мисля, че имат свои собствени тестове?

От една страна, наистина искам да се уверя, че XX и YY са направени според очакванията, преди да тествам ZZ. От друга страна, не искам ZZ да се провали поради дребни проблеми в XX или YY.

- person Steve Niles; 31.10.2012
comment
Да, ExactSpelling изглежда няма значение - person Steve Niles; 31.10.2012
comment
Моя грешка, ExactSpelling не е необходимо, ако е указано EntryPoint...Мисля, че това предупреждение е нормално, защото подобни предупреждения се появяват, когато компилирам x64 асембли (предупреждава за референтни асембли ) - person Jigsore; 31.10.2012