我想P/Invoke到GetWindowLongPtr和SetWindowLongPtr,我看到有关它们的相互矛盾的信息.
有些消息称,在32位平台上,GetWindowLongPtr只是一个调用GetWindowLong的预处理器宏,而GetWindowLongPtr不作为user32.dll中的入口点存在.例如:
因此,这些来源似乎表明*Ptr入口点根本不存在于32位Windows 7附带的user32.dll版本中.
但我在MSDN文档中没有看到这一点.根据MSDN,SetWindowLongPtr取代了SetWindowLong,简单明了.根据SetWindowLongPtr页面的要求部分,看起来SetWindowLongPtr自Windows 2000(客户端和服务器版本)以来一直在user32.dll中.同样,没有提到32位操作系统中缺少的入口点.
我怀疑事实介于两者之间:当你告诉C++编译器定位较旧的操作系统(即编译将在Win9x和NT4上运行的东西)时,头文件将SetWindowLongPtr声明为调用SetWindowLong的宏,但是入口点可能确实存在于Windows 2000及更高版本中,如果您告诉编译器定位这些平台,您将直接获取它(而不是宏).但这只是猜测; 我真的没有资源或技术可以深入挖掘并验证它.
目标平台也可能扮演一个角色 - 如果您为x86平台编译应用程序,那么就不应该在64位操作系统上调用SetWindowLongPtr.再一次,我知道这个问题,但我不知道如何找到答案.MSDN似乎暗示SetWindowLongPtr始终是正确的.
任何人都可以告诉我,简单的P/Invoke到SetWindowLongPtr是否安全并完成它?(假设Windows 2000及更高版本.)P /调用SetWindowLongPtr会给我正确的入口点:
我正在将一些代码从 .NET (4.5) 移动到 .NET Core (2) 并且有一个像这样的多目标项目......
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>net45;netcoreapp2.0</TargetFrameworks>
Run Code Online (Sandbox Code Playgroud)
代码库使用CopyMemory来自 kernel32的 Win32 API 函数,但我发现我需要根据我的目标框架使用不同的入口点名称。
#if NET45
[DllImport("kernel32.dll", EntryPoint = "CopyMemory", SetLastError = false)]
#else
[DllImport("kernel32.dll", EntryPoint = "RtlCopyMemory", SetLastError = false)]
#endif
public static extern void CopyMemory(IntPtr dest, IntPtr src, IntPtr count);
Run Code Online (Sandbox Code Playgroud)
我会认为这一切都比 .NET 低
所以,问题是……为什么?
我正在尝试使用,GetWindowLongPtrA但我一直收到“无法在DLL'user32.dll'中找到名为'GetWindowLongPtrA'的入口点”。(也会SetWindowLongPtrA出现相同的错误)。我已经尝试了许多在Google上找到的解决方案,但是他们没有解决。
这是我编写的函数的声明:
[DllImport("user32.dll")]
public static extern IntPtr GetWindowLongPtrA(IntPtr hWnd, int nIndex);
Run Code Online (Sandbox Code Playgroud)
尝试将put EntryPoint = "GetWindowLongPtrA",更改GetWindowLongPtrA为GetWindowLongPtr,put CharSet = CharSet.Ansi,切换为GetWindowLongPtrWwith CharSet = CharSet.Unicode等,它们都不起作用。
我的计算机正好是“ 64位”(但是不能调用该64位WinAPI函数吗?)。操作系统是Windows 10。
这个问题有什么解决方案?