因为现在的项目使用的是 AnyCpu 在 x86 的设备使用的是x86,在x64使用的是x64,但是对于非托管代码,必须要在x64使用x64的dll,在x86使用x86的dll。在C++没有和C#一样的 AnyCpu 所以需要在项目运行在x86的时候加载x86的dll。
本文告诉大家如何在代码引用不同的dll。
使用宏
最简单的方法是编译两个版本,编译多个版本可以点击配置管理器,然后创建x86和x64,然后版本添加宏,这样就可以判断宏来使用不同的dll
点击活动解决方案平台,然后点击新建
选择项目属性,点击生成,就可以添加不同的宏
于是在后台代码可以这样写
可以看到这个方法如果有很多个 dll 那么需要写很多路径
多个函数
实际上如果已经有两个dll ,那么可以使用两个不同函数
然后再写一个函数
这样就不需要在使用的时候判断当前使用的是哪个,但是如果dll多了,一个dll都需要写三次,看起来代码还是很烂
设置查找的文件
实际上好多人都觉得,应用程序首先是从运行的目录开始查找dll,如果找不到,就去GAC查找,如果还是找不到,就去System查找。实际上这句话是不对的,在没有设置默认查找的文件的时候就是这样,但是软件是可以设置查找文件。
设置的方法使用使用这个dll,请看下面
需要先把 x86 的 dll 放在程序的 x86文件夹,当然对于x64的大家也知道放哪里。
然后在程序运行的时候使用下面的代码
这样就可以直接写一个函数,最后的方法是我推荐的。
但是存在一些特殊的文件,他不能放在x86文件夹,所以就需要使用下面的代码特别加载
如果使用了 LoadLibrary
相对是比较复杂的做法,因为需要手动创建委托的方式。但是用 LoadLibrary
的好处是可以进行释放。
先创建一个类用来存在辅助的方法,请看代码
首先通过 LoadLibrary
加载 dll 请看下面代码
这样就可以拿到 dll 的指针,通过 GetProcAddress
可以拿到方法的指针
只是拿到了以为方法的指针是比较难调用的,所以就需要将方法指针转换
需要创建一个委托,签名和 dll 里的方法一样
注意这个委托需要标记UnmanagedFunctionPointer
才可以调用
通过 Marshal.GetDelegateForFunctionPointer
可以转函数指针为对应的类
这样就可以直接调用 C++ 的方法了,使用下面的代码调用
遇过遇到了 LoadLibrary
返回的 ptr 是 0 那么需要调用下面代码
通过 foo 的值在 System Error Codes (0-499) 就可以找到原因
需要注意,使用 GetLastWin32Error 必须设置 DllImport("xx.dll", SetLastError = true, CharSet = CharSet.Unicode)
才可以,当然最后的CharSet = CharSet.Unicode
不是一定需要
查看了项目的代码才看到,实际上还有一个方法,就是在运行的时候,如果当前运行的是x86的,就从x86文件夹复制dll出来,这个方法是速度最慢的。
原文链接: http://blog.lindexi.com/post/C-%E5%A6%82%E4%BD%95%E5%9C%A8%E9%A1%B9%E7%9B%AE%E5%BC%95%E7%94%A8x86-x64%E7%9A%84%E9%9D%9E%E6%89%98%E7%AE%A1%E4%BB%A3%E7%A0%81
本作品采用 知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议 进行许可。
欢迎转载、使用、重新发布,但务必保留文章署名 林德熙 (包含链接: https://blog.lindexi.com ),不得用于商业目的,基于本文修改后的作品务必以相同的许可发布。如有任何疑问,请与我 联系。