如何设置单声道dllimport的搜索路径?

我正在开发一个Unity应用程序,它需要从安装该应用程序的外部动态加载本机库,出于某种原因,我无法在编译之前设置绝对路径到DllImport (例如在运行时读取.txt中的库路径并加载它),我不想使用特定于平台的API,例如Windows上的LoadLibrary()或Linux上的dlopen ,因为这很不方便。 我一直在挣扎好几天。

我知道搜索路径可以通过Windows的SetDllDirectory()从这篇文章进行调整,并且在.NET Framework应用程序上进行测试时,它的效果很好。 然而,它不适用于基于mono 2.0的Unity,它只是在运行时抛出DllNotFoundException ,但在DllImport使用绝对路径或将dll复制到我的Unity项目时它工作正常(我确信代码是相同)

我尝试的下一个方法是环境变量,它不能在.NET和Mono上工作,这篇文章解释说CLR在进程执行期间从不刷新环境。

我尝试的第三种方法是使用特定于平台的API加载本地库,例如Windows上的LoadLibrary()和Linux上的dlopen() ,然后Dllimport可能会发现具有相同名称的库已经加载,然后它将使用加载库来查找函数指针,就像这篇文章所做的那样。 我得到了同样的结果。 该问题的最佳答案是,我们可以编写一个封装类,它使用特定于平台的API来显式加载库并获取函数指针,而不是一种聚焦Dllimport的方法,但这不是我想要的。

如果我的猜测是正确的,根据mono的文档, DllImportAttribute在运行时内部调用LoadLibrarydlopen以将库加载到内存空间。 因此它遵循特定OS平台的搜索规则,例如windows:

  • 加载应用程序的目录。
  • 当前目录
  • 系统目录。 使用GetSystemDirectory()函数获取此目录的路径。
  • 16位系统目录。
  • Windows目录。 使用GetWindowsDirectory()函数获取此目录的路径。
  • PATH环境变量中列出的目录。
  • 和Linux:

  • 用户的LD_LIBRARY_PATH环境变量中以冒号分隔的目录列表。 这是一种通过CLI程序可以找到本地共享库的常用方法。
  • 缓存在/etc/ld.so.cache中的库列表。 /etc/ld.so.cache通过编辑/etc/ld.so.conf并运行ldconfig(8) 。 编辑/etc/ld.so.conf是搜索其他目录的首选方式,而不是使用LD_LIBRARY_PATH ,因为这更安全(将木马库导入/etc/ld.so.cache比将它更加困难将其插入到LD_LIBRARY_PATH )。
  • /lib ,然后是/usr/lib
  • 顺便说一句,我也尝试在运行时设置LD_LIBRARY_PATH ,但它不起作用,因为LD_LIBRARY_PATH在进程启动时仅会被解析一次,这与Windows上的PATH环境变量类似。

    所以我的问题是:

  • 为什么相同的代码在.NET Framework和Mono上表现不同? Mono是否忽略了Windows上SetDllDirectory()的作用? DllImportAttribute在Mono中实际做了什么?
  • 是否有任何方法可以在运行时调整Unity / Mono应用程序的搜索路径,只需使用DllImport而不是特定于平台的API(如LoadLibrary()dlopen()

  • 不幸的是,答案是这种行为在Linux上的Mono和Windows上的.Net上是不同的,所以你只需要处理这个问题。

    最好的选择是,如果你知道每个DLL的位置(例如你可以把它放在配置文件中),就是使用LoadLibrarydlopen自己明确加载每个DLL。 这必须在第一次调用DllImport函数之前完成。 DllImport然后不需要指定路径。

    这样你就知道你正在得到哪个DLL,并且可以按照任何正确的顺序加载它们,如果这是个问题。

    如果由于某种原因,你真的不想这样做,我建议你创建一个像MySetDllDirectory这样的函数,它在Windows上调用SetDllDirectory并在Linux上设置LD_LIBRARY_PATH 。 通过这种方式,可以将更改隔离到单个模块。

    链接地址: http://www.djcxy.com/p/7753.html

    上一篇: How to set search path for dllimport in mono?

    下一篇: DLL depends another DLL but windows can't find it