题记:写这篇博客要主是加深自己对目录搜索的认识和总结实现算法时的一些验经和训教,如果有错误请指出,万分感谢。
介绍
公共语言基础设施(CLI)的目标是使它“容易”与现有代码进行互操作。原则上,所有您需要做的就是创立一个函数声明DllImport为现有的代码来调用,运行时将处置其余的。例如:
[DllImport ("libc.so")]
privatestaticexternint getpid ();
请注意,大多数的类和枚举提到在这个文档保存在System.Runtime.InteropServices namespace.
上面的c#函数声明将调用POSIX getpid(2)系统调用的平台上有 libc.so库
如果libc.so存在但getpid没有输出, 抛出一个EntryPointNotFoundException异常。如果libc.so不能加载, 抛出一个DllNotFoundException异常。简单,直接。有什么能比这更容易?
有三个问题
1 在DllImport语句指定库。
2 肯定实际调用哪个函数。
3 传递参数,大多数现有的代码更庞杂。字符串需要被传递,结构可能需要被传递,内存管理实际也将介入……
现有的代码是一个庞杂的怪兽,和互操作层需要支持这类庞杂性。
库处置
如何在运行时发明,并指定在DllImport属性中?这个问题本质上是特定于平台的。
Windows DLL搜索路径
从MSDNLoadLibrary文档,dll程序所需的是按照下面的次序进行搜索:
1. 应用程序加载的目录。
2. 当前目录
3. 系统目录,应用GetSystemDirectory()函数来取得这个目录的路径。
4. 16位系统目录。
5. Windows目录。应用GetWindowsDirectory()函数来取得这个目录的路径。
6. PATH环境变量中列出的目录。
当然,事实并没有那么简单。实际上,“system”目录实际上是%WINDIR%\system32,除了Windows9x平台%WINDIR%\system。16位系统目录通常%WINDIR%\system,但不被视为一个单独的搜索目录在Windows 9 x平台。
此外,在Windows Server 2003和Windows XP SP1, 注册表进口HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\SessionManager\SafeDllSearchMode转变上述命令, 如果这是1(默认),然后搜索当前目录是在系统和Windows目录。这是一个安全特性(它可以防止木马库被载入取代,例如,OLE32.DLL) 但它把上面的列表改成:1、3、4、5、2、6。
Linux同享库搜索路径
从dlopen(3)手册页,必要的程序所需的同享库是按照下面的次序进行搜索:
1在用户的LD_LIBRARY_PATH 环境变量中以冒号分开的目录列表.这是一个经常应用的方法,答应本地同享库是一个CLI程序发明的。
2库的列表,缓存在/etc/ld.so.cache. /etc/ld.so.cache是由编辑/etc/ld.so.conf和运行ldconfig. 编辑/ etc/ld.so.conf首选方法是搜索附加目录,而不是应用LD_LIBRARY_PATH, 因为这是更安全的(很难达到一个木马库到/ etc/ld.s.cache比插入到LD_LIBRARY_PATH)。
3 / lib,紧随其后的是/ usr / lib。
作为一个mono的扩展, 如果一个库正被加载是__Internal,然后主程序是寻找方法符号。这相当于调用dlopen(3)和一个文件名的空。这答应您P / Invoke方法,都在一个应用程序嵌入Mono。
Mac OS X框架和.dylib搜索路径
框架和库搜索路径是:
1在用户的DYLD_FRAMEWORK_PATH环境变量中以冒号分开的目录列表.
2在用户的 DYLD_LIBRARY_PATH环境变量中以冒号分开的目录列表.
3在用户的 DYLD_FALLBACK_FRAMEWORK_PATH 环境变量中以冒号分开的目录列表.它是默认目录:
· ~/Library/Frameworks
· /Library/Frameworks
· /Network/Library/Frameworks
· /System/Library/Frameworks
4在用户的 DYLD_FALLBACK_LIBRARY_PATH 环境变量中以冒号分开的目录列表, 它是默认目录:
· ~/lib
· /usr/local/lib
· /lib
· /usr/lib
注意:应用GLib,Mono加载库, 还有在Mac OS X上GLib有bug不应用,..dylib扩展,而是应用Unix.so extension,虽然这应当最终被修复, 目前的解决方法是写一个.config文件映射到.dylib文件
<configuration>
<dllmapdll="mylib"target="mylib.dylib"/>
</configuration>
TODO:将mono同时支持框架和dylibs吗?
库名:
知道到哪里查找库是只有一半的问题。了解库的加载是另一半。
不同的平台有不同的命名约定。Windows平台上是库名.dll,如OLE32.DLL等。Linux平台应用lib前缀和一个.so后缀。MacOSX平台应用lib前缀和一个.dylib后缀。除非他们是一个框架,在这类情况下,他们是一个目录,事件变得更加庞杂。
文章结束给大家分享下程序员的一些笑话语录:
人工智能今天的发展水平:8乘8的国际象棋盘其实是一个体现思维与创意的强大媒介。象棋里蕴含了天文数字般的变化。卡斯帕罗夫指出,国际象棋的合法棋步共有1040。在棋局里每算度八步棋,里面蕴含的变化就已经超过银河系里的繁星总数。而地球上很少有任何数量达到这个级别。在金融危机之前,全世界的财富总和大约是1014人民币,而地球人口只有1010。棋盘上,所有可能的棋局总数达到10120,这超过了宇宙里所有原子的总数!经典语录网
---------------------------------
原创文章 By
目录和搜索
---------------------------------