在 Mono for Mac 上设置 DllImport 的本机库路径

2023-11-24

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

但是当 P/Invoke 进入这个 dll 时,我得到一个 DllNotFound 异常。我通读了Mono 互操作维基并且 Mono 上的 P/Invoke 似乎只会查看 DYLD_* 环境变量指向的位置,并且当前目录不在搜索路径中。当我将框架复制到 /Library/Frameworks 时,我的 P/Invoke 调用工作正常,但我希望我的框架文件出现在应用程序旁边,而不是在 /Library/Frameworks 中。

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

无论如何,我是否可以将我的框架文件保留在应用程序旁边,并且仍然可以进行 P/Invoke?


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

设置环境变量

您可以在环境变量中设置LSEnvironment您的应用程序的部分Info.plist, 像这样:

    <?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 处理它的方式;也可以看看苹果的文档.

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

我建议使用创建一个 app.config 文件<dllmap>,因此您无需将任何路径名放入代码中,从而更轻松地更改框架版本。例如:

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

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

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在 Mono for Mac 上设置 DllImport 的本机库路径 的相关文章

随机推荐