7

私がMonoforMacに移植しているコードは、アンマネージC++ライブラリを呼び出します。Macでは、アンマネージライブラリをフレームワークに移植しました(残念ながら、ビルドプロセスでは、フレームワークとしてのみコンパイルでき、dylibとしてはコンパイルできません)。Monoでは、ビルドしたアプリの横にフレームワークファイルをコピーするために、プロジェクトにビルド後のステップを設定しました。

しかし、このdllにP / Invokeを実行すると、DllNotFound例外が発生します。Mono Interop Wikiを読みましたが、 MonoでのP / Invokeは、DYLD_ *環境変数が指す場所のみを参照し、現在のディレクトリは検索パスに含まれていないようです。フレームワークを/Library/ Frameworksにコピーしたとき、P / Invoke呼び出しは正常に機能しましたが、Frameworkファイルを/ Library / Frameworksではなく、アプリの横に配置することをお勧めします。

P / Invoke呼び出しを行う前に、コードのDYLD_FRAMEWORK_PATH環境変数に現在の作業ディレクトリを追加しようとしましたが、System.Environment名前空間の機能がMono for Macで制限されており、環境変数の取得または設定はサポートされていません。

とにかく、フレームワークファイルをアプリの隣に置いて、P / Invokeを使用することはできますか?

4

1 に答える 1

8

これを2つの質問に分けてみましょう。環境変数を設定する方法と、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>

そのファイルを一度手動で編集し、少なくとも1つの環境変数を追加する必要があるようです。

ファイルはMonoDevelopによって自動的に作成されるため、LSEnvironmentセクションを追加するだけです。

その後、MonoDevelopでそれらを編集できます。プロジェクトオプション、「Mac OS Xアプリケーション」、「詳細」に移動します。

MonoMacアプリケーションでのネイティブフレームワークのバンドル

ネイティブフレームワークをMonoMacアプリケーションにバンドルするために環境変数を設定する必要はありません。これを行うには、はるかに簡単でクリーンな方法があります。これは、ObjectiveCでの動作と同様です。

ネイティブのObjectiveCアプリケーションとMonoMacアプリケーションの両方にフレームワークをバンドルする小さなテストアプリケーションを作成しました。

最初に行う必要があるのは、フレームワークをアプリにバンドルすることです。現在、MonoDevelopでこれを自動的に行う方法はないため、ファイルを手動でコピーするか、ビルド後のスクリプトを使用する必要があります(copy-framework.sh私の例を参照)。

YourApp.app/Contents/Frameworks/YourFramework.frameworkXCodeがフレームワークを処理する方法であるため、フレームワークを組み込むことをお勧めします。Appleのドキュメントも参照してください。

アプリケーションバンドル内のライブラリを参照するには、 `@ executeable_path'を使用できます(dyldのマニュアルページを参照)。

を使用してapp.configファイルを作成することをお勧めします<dllmap>。これにより、コードにパス名を入力する必要がなくなり、フレームワークのバージョンを簡単に変更できるようになります。例えば:

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

フレームワーク内の実際のライブラリが/で始まるか、 /でlib終わる場合は、その名前を指定する必要があります(たとえば、上記のdllmapはファイルされません)。これはMonoのバグで、修正したばかりです。.so.dylibTestFramework.framework/libTestFramework.dylib

于 2012-10-11T13:40:39.553 に答える