为Mac版Mono上的DllImport设置本机库的路径



我正在移植到Mono for Mac的代码,调用到非托管C++库中。在Mac上,我已经将我们的非托管库移植到了一个框架中(不幸的是,我们的构建过程只允许将其编译为一个框架,而不是dylib)。在Mono中,我在项目中设置了一个构建后步骤,将框架文件复制到构建的应用程序旁边。

但是当p/Invoke进入这个dll时,我会得到一个DllNotFound异常。我阅读了Mono Interop Wiki,Mono上的P/Invoke似乎只会查看DYLD_*环境变量指向的位置,而当前目录不在搜索路径中。当我将框架复制到/Library/Frameworks时,我的P/Invoke调用运行良好,但我更希望我的框架文件出现在应用程序旁边,而不是/Librare/Frameworks中。

在进行任何p/Invoke调用之前,我尝试将当前工作目录添加到代码中的DYLD_FRAMEWORK_PATH环境变量中,但System.environment命名空间在Mono for Mac上的功能有限,不支持获取或设置环境变量。

我是否可以将我的框架文件放在应用程序旁边,并且仍然标记为p/Invoke?

让我们将其分为两个问题:如何设置环境变量以及如何在MonoMac应用程序中捆绑本机框架。

设置环境变量

您可以在应用程序的Info.plistLSEnvironment部分设置环境变量,如下所示:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleIdentifier</key>
<string>com.yourcompany.TableViewTest</string>
<key>CFBundleName</key>
<string>TableViewTest2</string>
<key>CFBundleVersion</key>
<string>1</string>
<key>LSMinimumSystemVersion</key>
<string>10.6</string>
<key>NSMainNibFile</key>
<string>MainMenu</string>
<key>NSPrincipalClass</key>
<string>NSApplication</string>
<key>LSEnvironment</key>
<dict>
<key>Foo</key>
<string>Bar</string>
</dict>
</dict>
</plist>

似乎必须手动编辑该文件一次,并添加至少一个环境变量。

该文件是由MonoDevelop自动创建的,所以您所要做的就是添加LSEnvironment部分。

之后,您可以在MonoDevelop中编辑它们:转到项目选项,"Mac OS X应用程序","高级"。

在MonoMac应用程序中捆绑本机框架

您不需要设置任何环境变量就可以在MonoMac应用程序中捆绑本机框架,有一种更简单、更干净的方法可以做到这一点,这也类似于Objective C.中的工作方式

我创建了一个小型测试应用程序,它将一个框架捆绑在本地Objective C应用程序和MonoMac应用程序中。

你需要做的第一件事是将你的框架与应用程序捆绑在一起。目前在MonoDevelop中没有自动完成这项工作的方法,因此您需要手动复制文件或使用一些后期构建脚本(请参阅我的示例中的copy-framework.sh)。

我建议将该框架放入YourApp.app/Contents/Frameworks/YourFramework.framework中,因为XCode就是这样处理它的;另请参阅Apple文档。

要引用应用程序包中的库,可以使用"@executable_path"(请参阅dyld手册页)。

我建议使用<dllmap>创建一个app.config文件,这样您就不需要在代码中放入任何路径名,从而更容易更改框架版本。例如:

<configuration>
<dllmap dll="TestFramework" target="@executable_path/../Frameworks/TestFramework.framework/TestFramework" />
</configuration>

如果框架中的实际库以lib开头或以.so/.dylib结尾,则必须指定该名称(例如,上面的dllmap不会归档TestFramework.framework/libTestFramework.dylib)。这是Mono中的一个错误,我刚刚修复了它。

相关内容

最新更新