3

Unity3DproでCコードを使用しようとしています。

私の基本的なアプローチは、(1)Cソースコードを静的ライブラリにビルドする(2)空のバンドルを作成してライブラリにリンクする(3)バンドルをUnity 3D proに(プラグインとして)インポートすることです。

私は基本的にこのチュートリアルに従っていました。

Cコードを更新し、ライブラリとバンドルを再コンパイルして再構築していた最近まで、しばらくの間機能していましたが、すべてがうまくいきません...

バンドルを最初にインポートしたときに、DllNotFoundExceptionが発生しました。

その段階では、私のバンドルプロジェクトは単なるライブラリの山でした-ソースコード(.aファイル)から構築されたライブラリと、.aライブラリが依存していると思う他のいくつかのライブラリ(他のライブラリには.dylib拡張子が付いています) )。

バンドルにtest.cファイルを1つ追加しました。test .cファイルには、次の2行しか含まれていません。

#include <stdio.h>
#include "ccn.h"

char* say()
{
    return "hi";
}

ここで、ccn.hは私のCソースコードのヘッダーファイルです。

バンドルを再構築した後、DllNotFoundExeptionはなくなりましたが、EntryPointNotFoundExceptionが発生しました。

これが私が考えていることです:

  1. Xcodeは非常にインテリジェントであるため、単純なtest.cファイルを追加しているときに、Xcodeがバンドル設定の一部を変更してくれたと思います。そして、それがDllNotFoundExceptionが最初になくなった理由だと思います。私は正しいと思いますか?
  2. EntryPointNotFoundの問題を解決するために、バンドルプロジェクトの設定も変更する必要があると思いますが、方法がわかりません...助けてください...

たくさんの感謝!

編集

  1. このスレッドは、Xcodeがコンパイルにg ++を使用しているため、アンマネージコードが純粋なCであっても、extern"C"が必要であることを示唆しているのを見ました。Xcode4のターゲット設定を" Compiler for C / C ++/Objective-C "に変更しました。 AppleLLVM3.0からLLVMGCC4.2に移行しましたが、それでも同じ例外が発生します。
  2. また、monoがライブラリをロードするためにGLibを使用していることを示すこのmonoのドキュメントを見ました。また、GlibにはMac OS Xにバグがあり、.dylibライブラリを認識しません。.dylibライブラリを削除して再試行しましたが、同じ例外が発生するまで続きました。
  3. また、 Appleのドキュメントには、ロード可能なすべてのバンドルにプリンシパルクラスが必要であると記載されており、ユーザーがどのクラスをプリンシパルクラスにするかを指定しない場合、NSBundleはXcodeプロジェクトに示されている最初のクラスをプリンシパルクラスとして使用します。さて、私が作成したバンドルはロード可能なバンドルだと思いますが、それは単にCから構築された静的ライブラリであるため、文字通りクラスがありません。プロジェクトのinfo.plistを見ると、プリンシパルクラスのエントリは空です。これが問題でしょうか?もしそうなら、どうすればそれを解決できますか?
  4. また、私はAppleのドキュメントで、私がよく理解していない何かを見ました。

    ロード可能なバンドルがプラグインの場合、ホストアプリケーション開発者は通常、フレームワークでプラグインアーキテクチャのインターフェイスを提供します。このフレームワークには通常、すべてのプラグインプリンシパルクラスが継承するクラス、またはプラグインのプリンシパルクラスが採用するプロトコル(公式または非公式)が含まれています。

    私が作成するロード可能なバンドルはプラグインであると確信しています。バンドルをUnity3Dにインポートしています。Unityからプリンシパルクラスを定義する必要があるということですか?どのように?

4

1 に答える 1

2

この問題には簡単な解決策があります。

最初に、test.cファイルでEntryPointNotFoundExceptionを発生させている関数を試してください。

「試してみる」とは、main()で関数を呼び出して、最初にCでテストすることを意味します。

私の場合、EntryPointNotFoundExceptionをスローする関数はccn_run()と呼ばれます。だから私は次のことをしました:

  1. main()関数をtest.cに追加します
  2. main()関数にccn_run()と入力します
  3. Xcodeプロジェクトにコマンドラインターゲットを追加してテストします

私はそれを試してみましたが、関数はCで正常に動作しています。今では、バンドルを再構築すると(main()関数とその中のccn_run()呼び出しを削除せずに)、Unityがccn_run()関数を呼び出すことができます。問題なく!

これが私の問題を解決する理由を説明することはできませんでしたが、これはほぼ1か月間私のために働いています。少し前にXcodeが4.3.2にアップグレードされ、同じアプローチを再試行しましたが、それでも機能します。main()関数を追加すると、エントリポイントの定義に役立つと思いますか?

最後に、CコードをUnityにインポートするプロセス全体を文書化しました。ここで共有できてうれしいです:https ://docs.google.com/document/d/1vAeupNQlBTY3y3Bma5Jo_Hs4JRYm6FoEc4vQN0WBGNg/edit

私のコードサンプル:

  1. Xcodeプロジェクト:https ://github.com/CherryQu921/CCNxPlugin
  2. Unityプロジェクト:https ://github.com/CherryQu921/cqs

この答え、特に私のチュートリアルがお役に立てば幸いです。

于 2012-04-28T22:16:21.993 に答える