gpt4 book ai didi

.net - .NET 与 .NET Core 2 的不同 P/Invoke 入口点

转载 作者:可可西里 更新时间:2023-11-01 09:47:10 25 4
gpt4 key购买 nike

我正在将一些代码从 .NET (4.5) 移动到 .NET Core (2),并且有一个像这样的多目标项目...

<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>net45;netcoreapp2.0</TargetFrameworks>

代码库使用来自 kernel32 的 Win32 API 函数 CopyMemory,但我发现我需要根据我的目标框架使用不同的入口点名称。

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

我原以为这一切都处于低于 .NET 的水平

那么,问题是……为什么?

最佳答案

如果您想要可预测的结果,请求 CopyMemory 实际上是一个非常糟糕的主意。对于初学者来说,没有非托管应用程序调用任何名为 CopyMemory 的函数,因为它被定义为 Windows header 中 C memcpy 函数的简单别名。 kernel32.dll 中根本没有CopyMemory 导出,RtlCopyMemory 是否可用取决于您的平台。当您要求对 CopyMemory 进行 P/Invoked(如果有)时,用于导入哪些函数的逻辑因平台而异。这是适用于 Windows 10 的小表格:

+--------------+---------------+------------------------------+
| Platform | ExactSpelling | Resulting unmanaged function |
+--------------+---------------+------------------------------+
| .NET, 32-bit | true | - |
| .NET, 64-bit | true | - |
| .NET, 32-bit | false | RtlMoveMemory |
| .NET, 64-bit | false | memmove |
+--------------+---------------+------------------------------+

对于 .NET Core,逻辑要简单得多:.NET Core 不关心这种向后兼容的废话。如果您请求 kernel32!CopyMemory,天哪,它会尝试为您提供 kernel32!CopyMemory。由于根本没有这样的导出,它将失败。对于 64 位和 32 位运行时都是如此。

在 64 位 Windows 上 RtlCopyMemory 实际上作为导出存在,这就是它适用于 .NET Core(以及 64 位 .NET Framework)的原因。但值得注意的是,该文档根本不保证它存在,因此依赖它似乎是不可取的——除了更基本的问题,它会使您的代码在 Windows 以外的任何设备上都不可移植。

从 .NET 4.6 开始,Buffer.MemoryCopy提供了一种可移植的替代方案,在 .NET Core 2.0 中也可用。如果您必须 P/Invoke 到 native 函数(希望只是作为权宜之计),您最好 P/Invoking 到 RtlMoveMemory,因为它存在于 32-位和 64 位 Windows:

[DllImport("kernel32.dll", EntryPoint = "RtlMoveMemory", ExactSpelling = true)]
public static extern void CopyMemory(IntPtr dest, IntPtr src, IntPtr count);

对于两种位数,这将在 .NET Core 和 .NET Framework 上正常工作(当然,只要您在 Windows 上运行)。

关于.net - .NET 与 .NET Core 2 的不同 P/Invoke 入口点,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47014586/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com