针对“任何 CPU”的 .NET 应用程序是否可以运行?在多个环境中使用 P/Invoke 调用?
我有一个使用一些 API 调用的 .NET 应用程序,例如 GetPrivateProfileString。到目前为止它一直运行在32位机器上。
为了在 64 位机器上运行,我必须将“平台目标”更改为“x86”吗?或者有没有办法让运行时知道根据运行时环境调用哪个API DLL?
I have a .NET application that uses some API calls, for example GetPrivateProfileString. So far it has always run on 32-bit machines.
In order to run on 64-bit machines, must I change the "Platform Target" to "x86"? Or is there a way to let the runtime know which API DLL to invoke depending on the runtime environment?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您需要确保仅对 64 位 DLL 使用 P/Invoke 调用。
一种选择是将所有“方法”移至标准接口(或抽象基类)中,并提供 2 种实现,一种 32 位,一种 64 位。您可以使用工厂方法根据 IntPtr 的大小构造适当的类实例。
这允许“AnyCPU”应用程序在运行时正确确定要 P/调用哪个 DLL,并且可以正常工作。
You need to make sure that you're only using P/Invoke calls against a 64bit DLL.
One option is to move all of your "methods" into a standard interface (or abstract base class), and provide 2 implementations, one 32bit and one 64bit. You can have a factory method construct the appropriate instance of the class depending on the size of IntPtr.
This allows an "AnyCPU" app to correctly, at runtime, determine which DLL to P/Invoke into, and does work.
如果您 P/Invoke 导出的 DLL 也可以在 64 位版本中使用,那么您将没有任何问题。对于 Windows DLL(例如 kernel32.dll)来说,情况确实如此。 GetPrivateProfileString() 也可以正常工作,您不需要使 [DllImport] 属性有任何不同。假设您在需要时使用了 IntPtr。
当您使用过时或 Windows 中未包含的第 3 方 DLL 或 COM 服务器时,几率会降低。您很快就会发现是否需要 x86 目标平台覆盖,运行时异常声音足够大。对于 pinvoked DLL,您将收到 BadImageFormat 异常,32 位 COM 服务器会生成“类未注册”异常。
You'll have no trouble if the DLL whose export you P/Invoke is also available in a 64-bit version. Which is definitely the case for the Windows DLLs, like kernel32.dll. GetPrivateProfileString() will work just as well, you don't need to make the [DllImport] attribute any different. Assuming you used IntPtr where required.
Odds get lower when you use a 3rd party DLL or a COM server that is outdated or not included with Windows. You'll find out quickly if the x86 Target platform override is required, the runtime exception is loud enough. You'll get a BadImageFormat exception for pinvoked DLLs, 32-bit COM servers produce a "Class Not Registered" exception.