C#,如何分别在x64和x86平台上加载同一个名称的原生dll
以sqlite-net为例:
1、定义API
1 2 | [DllImport( "kernel32.dll" , CharSet = CharSet.Auto, SetLastError = true )] static extern bool SetDllDirectory( string lpPathName); |
2、在static SQLite3()中,加入下列代码
1 2 3 4 5 6 7 8 9 10 | static SQLite3() { //https://stackoverflow.com/questions/4385806/determine-the-loaded-path-for-dlls/4385997 SetDllDirectory( null ); // Reset. SetDllDirectory( "" ); // Plug "binary planting" security hole. ` string dllpath = IntPtr.Size == 8 ? "x64" : "x86" ; dllpath = $ "{AppDomain.CurrentDomain.BaseDirectory}{dllpath}" ; //BaseDirectory 有分隔符结尾 bool ret = SetDllDirectory(dllpath); if (!ret) throw new System.ComponentModel.Win32Exception(); } |
3、在exe文件的启动目录下新建x64和x86两个目录,分别将64位和32位的sqlite3.dll放入对应的目录里。
4、记住,要在退出程序之前重置搜索顺序。请使用 null 和 空串 分别调用一次 SetDllDirectory
说明:
在windows中,假如安全DLL搜索模式启用,搜索顺序如下:
1. 应用程序所在的路径
2. Windows SYSTEM目录。通过调用GetSystemDirectory函数可以获取这个目录的路径。
3. 16位系统的目录。并没有函数可以获取这个目录的路径,但是它会被查找。
4. Windows目录。通过调用GetWindowsDirectory函数可以获取这个目录的路径。
5. 当前目录
6. PATH环境变量指定的路径。请注意,这并不包括每个应用程序的应用程序路径注册表项中指定。在应用程序路径注册表项的键值并不作为DLL的搜索路径。
BOOL SetDllDirectoryA([in, optional] LPCSTR lpPathName);
参数 [in, optional] lpPathName
要添加到搜索路径的目录。如果此参数为空字符串 (""),则调用将从默认 DLL 搜索顺序中删除当前目录。
如果此参数为 NULL,则该函数将恢复默认搜索顺序。
返回值
如果函数成功,则返回值非零。
如果函数失败,则返回值为零。要获取扩展错误信息,请调用 GetLastError。
说明
该 SetDllDirectory会功能会影响到所有后续调用 的LoadLibrary和 LoadLibraryEx功能。当指定目录在搜索路径中时,它还有效地禁用安全 DLL 搜索模式。
对于未运行打包或受保护进程的Win32 进程,调用此函数还会影响从调用该函数的进程开始的子进程的 DLL 搜索顺序。
调用 SetDllDirectory 后,标准的 DLL 搜索路径为:
1. 应用程序加载的目录。
2. lpPathName参数指定的目录。
3. 系统目录。使用 GetSystemDirectory函数获取该目录的路径。该目录的名称是 System32。
4. 16 位系统目录。没有获取这个目录路径的函数,但是会搜索。该目录的名称是 System。
5. Windows 目录。使用 GetWindowsDirectory函数获取该目录的路径。
6. PATH 环境变量中列出的目录。
每次调用SetDllDirectory函数时,它都会替换上一次SetDllDirectory调用中指定的目录。要指定多个目录,请使用AddDllDirectory函数并使用LOAD_LIBRARY_SEARCH_USER_DIRS调用LoadLibraryEx。
要恢复到LoadLibrary和 LoadLibraryEx使用的标准搜索路径 ,请使用 NULL调用 SetDllDirectory。这还会根据SafeDllSearchMode注册表值恢复安全的 DLL 搜索模式。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
2019-05-20 VBA通过C#以API方式调用JS脚本函数
2014-05-20 WinForm 进度条