gpt4 book ai didi

pinvoke - 在 Mono for Mac 上为 DllImport 设置 Native Library 的路径

转载 作者:行者123 更新时间:2023-12-04 14:47:38 25 4
gpt4 key购买 nike

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

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

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

无论如何我可以将我的框架文件放在应用程序旁边并且仍然可以使用 P/Invoke 吗?

最佳答案

让我们把它分成两个问题:如何设置环境变量以及如何在 MonoMac 应用程序中捆绑 native 框架。

设置环境变量

您可以在 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 应用程序中捆绑 native 框架

您不需要设置任何环境变量来在 MonoMac 应用程序中捆绑 native 框架,有一种更简单、更清晰的方法来做到这一点,这也类似于 Objective C 中的工作方式。

我创建了一个小 test applications ,它在 native Objective C 应用程序和 MonoMac 应用程序中捆绑了一个框架。

您需要做的第一件事是将您的框架与应用程序捆绑在一起。目前在 MonoDevelop 中无法自动执行此操作,因此您需要手动复制文件或使用一些后期构建脚本(参见我的示例中的 copy-framework.sh)。

我建议将框架放入 YourApp.app/Contents/Frameworks/YourFramework.framework因为这就是 XCode 处理它的方式;另见 Apple's Documentation .

要在应用程序包中引用库,可以使用 `@executable_path'(参见 dyld man page)。

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

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

关于pinvoke - 在 Mono for Mac 上为 DllImport 设置 Native Library 的路径,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12834141/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com