Unity与本地库交互

介绍

 

公共语言基础设施(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%\system16位系统目录通常%WINDIR%\system,但不被视为一个单独的搜索目录在Windows 9 x平台。

 

此外,Windows Server 2003Windows XP SP1, 注册表入口HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\SessionManager\SafeDllSearchMode改变上述命令, 如果这是1(默认),然后搜索当前目录是在系统和Windows目录。这是一个安全特性(它可以防止木马库被载入代替,例如,OLE32.DLL) 但它把上面的列表改为:134526

 

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 XGLibbug不使用,..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后缀。除非他们是一个框架,在这种情况下,他们是一个目录,事情变得更加复杂。

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值