如何根据CPU架构使用正确的非托管.dll?
我在 .net 应用程序中使用非托管库,该库在 x86 和 64 位系统上使用,因此被编译为“任何 CPU”。然而,非托管的本机 .dll 有两种不同的 .dll(一种用于 win32,一种用于 x64)。
对于 x86 和 x86 的 P/Invoke 签名,是否有任何方法仍然可以使用不同的本机 .dll 保留“任何 CPU”/一种二进制方式? 64位系统?或者 - 是 - 创建单独的配置和配置的唯一方法因此分布?如果是这样,我可以使用任何编译 #if/#endif 标志吗?
I am using an unmanaged library in a .net application which is used on x86 and 64bit systems alike and therefore is compiled as 'Any CPU'. The unmanaged, native .dll however comes in two different .dlls for that (one for win32 and one for x64).
Is there any way to still keep the 'Any CPU' / one binary way with different native .dlls regarding the P/Invoke signatures for x86 & 64bit systems? Or -is- the only way to create separate configs & therefore distributions? If so, are there any compile #if/#endif flags I can use for that?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
在 bin 文件夹中,您可以添加另外两个名为
x86
和x64
的文件夹。这些文件夹将包含本机 DLL 的 x64 和 x86 映像。启动时(在应用程序加载任何外部 DLL 之前),您可以修改您的 进程的
PATH
环境变量它将根据进程的位数包含适当的子目录(IntPtr.Size
应指示您的位数)。对于托管 DLL 探测,您可以订阅 AppDomain.AssemblyResolve 事件,这样您就可以自己从正确的子目录加载程序集(例如使用 Assembly.Load)。
In your bin folder, you could add an additional two folders named
x86
andx64
. These folder will contain the x64 and x86 images of your native DLL.On startup (before your application loads any external DLLs), you could modify your process's
PATH
environment variable so it will include the appropriate sub-directory according to the process's bitness (IntPtr.Size
should indicate your bitness).For managed DLL probing, you could subscribe to the AppDomain.AssemblyResolve event, so you could load the assembly from the correct sub-directory by yourself (e.g. by using Assembly.Load).
我会将 p/invoke 代码放入单独的程序集中(一个用于 32 位,一个用于 64 位),然后 根据平台在运行时加载适当的。
有多种方法可以确定系统的类型。 此处记录了很多内容。
I would put the p/invoke code into a seperate assemblies (one for 32 and one for 64 bits) and then load the appropriate one at run time depending upon the platform.
There are many ways to determine the type of the system. Lots are documented here.
您可以手动调用
LoadLbrary
&GetProcAddress
,通过调用Marshal.GetDelegateForFunctionPointer(procAddress, delegateType)
将函数指针转换为委托。这会产生更多代码,但允许您将所有互操作代码保留在单个程序集中。例如 NHanspell 就使用了这种方法。You can manually call
LoadLbrary
&GetProcAddress
, convert function pointers to delegates by callingMarshal.GetDelegateForFunctionPointer(procAddress, delegateType)
. This results in more code but lets you keep all interop code in a single assembly. This approach is used by NHanspell for example.