• C#,如何分别在x64和x86平台上加载同一个名称的原生dll


    以sqlite-net为例:

    1、定义API

    [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
    static extern bool SetDllDirectory(string lpPathName);
    

    2、在static SQLite3()中,加入下列代码

    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 搜索模式。

  • 相关阅读:
    WebView.自动登录
    Android.对话框(AlertDialog/Toast/Snackbar)
    ubuntu解压rar
    sqlserver2005 存储过程模板及调用
    win7 32位下装oracle 10g报未知错误
    oracle下常用查询更新命令(身份证号判断男女,更新语句多表查询)
    如何建立一个android工程
    ubuntu14.04 配置android及sdk等相关操作
    mysql 常用简单的几个命令
    linux的tar简单使用
  • 原文地址:https://www.cnblogs.com/Charltsing/p/SetDllDirectory.html
Copyright © 2020-2023  润新知