72
65

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

UnityでC++のコードを呼び出すのを検証中

Last updated at Posted at 2014-09-13

1.はじめに

UnityでC++のコードを呼び出すことをしたかったので調べた結果を残しておきたいと思います。
ただし、自分はUnityの無料版を使っており、Pro版では呼び出せるということは多くの記事に載っているのですが、無料版でできるかどうかはまだ実際にはやっていないので後日その結果はまた更新します。(新着情報のところに記述しましたが、あるサイトによるとできるぽいです。)

2.C#でC++のコードで作ったダイナミックライブラリを呼び出す

UnityはC#、JavaScript、Booの3つの言語をスクリプトとして利用できるのですが、C++はその中に入っていません。では、どうやって使うかというと、C++をDLL化して呼び出す必要があるとのことです。
ただし、DLL化というのはWindowsでしかできないので、Macユーザーの自分はC++を利用できないかと思ったら、dylibというのが、WindowsのDLLと同じものらしいので、それでできるのではないかっと思ってまずは、C++のコードをdylib化する方法を調べました。

2.1.C++のコードをdylib化

この記事とは別にdylib化については別の記事にしてあるのでそちらを参考にしてください。

記事:c++ファイルのダイナミックライブラリdylibの作り方

記事を読んでいただければやり方はとても簡単なのは分かると思います。
ただ、このやり方を見つけるのはすこし時間がかかりました(^^;)

2.2.C#でDLL化したものを呼び出す

この方法はP/Invoke(Platform Invoke)というらしいです。ちなみに、"Invoke"とは『(神などに)救いを求めて呼びかける、祈る、呼び出す』という意味(weblio辞典より)らしいので単純にプラットフォームを呼び出すというよりも、藁をもつかむような思いがあるのかもしれないですね。←ジョークです。

さて、本題に入って、まず、作ったDLLをAssets/Pluginsの下に置くらしいです。そして、Unity側でDLLの関数を静的リンクで呼び出すのは、DllImport属性を使って宣言すれば良いらしいです。

[DllImport("hello.dll")] private static extern IntPtr LoadLibrary(String lpFileName);

こうゆう感じに宣言すればLoadLibraryを呼び出せるとのこと。ただ、これだとDLL名がコンパイル時に判明しておかないと行けないので、DLLの名前が実行時にしかわからないものを使う時はまた違う作業が必要らしいですが、今回はそこに時間をかけれないので、そちらについて知りたい方は参考サイトの方にリンク(*2)をはっておきますので、各自ご確認くださいm(_ _)m

2.3.C#でdylibを呼び出す

申し訳ないのですが、ここからは明確な記述がある記事を見つけれなかったので推測です。まぁ、なので、たぶん拡張子をdylibで書けばいけるはず。なのでこんな感じ?↓

[DllImport("hello.dylib")] private static extern IntPtr LoadLibrary(String lpFileName);

っと思っていたら、こんな記事が...
記事:unityでdylibが読み込めない問題
この記事によると、dylibが読み込めないらしいです。
まぁ、この記事に解決策が書かれていて、dylibの拡張子をbundleに変えればいいとのこと。
環境によってはconfigファイルをいじればいいらしいです。
具体的には

"/Applications/Unity/Unity.app/Contents/Frameworks/Mono/etc/mono/config"にdllmapを定義する

とのこと。
実は、ここではこの方はconfigファイルをいじったけどダメだったらしく、この方の記事を追いかけていたら解決方法が書かれていました。
記事:Unityでframeworkを読み込む

さて、これが無料版でできるか。できたらまた報告します。
Unityについてはまだまだ分からないことがたくさんあるので知っている方がいらっしゃいましたら教えてくださいm(_ _)m

2.4.新着情報

【2014.09.14.12:00頃】
Unityで実行させようとスクリプトに
[DllImport("hello.dll")] private static extern IntPtr LoadLibrary(String lpFileName);
を記述したところ、DllImportに赤の下線が引かれてしまったのでこれをどうすればいいのかと思って検索をしていたら、
記事:Unity and DLLs: C# (managed) and C++ (unmanaged)
というサイトを発見しました。
このサイトによると、無料版でもPro版でもC++を呼び出すことはできるとのこと!
ただ、このサイトが紹介しているのはWindows版なので、これからこのサイトの情報も確認しつつ検証してみようと思っています。
また、新着がありましたら新着情報として載せていきます。


【2014.09.19.2:50頃】
なかなか検証を行うのがちょっと億劫になってしまってようやくまた手をつけ始めたのですが、ネットで検索していたら、xcodeでダイナミックライブラリを作成すればかんたんなのかもしれない事実が浮上。
記事:MacOS向けのNativePluginを作成する

こちらの記事を参考にしてちょっと実験をこれからしてみたいと思います。結果が出ましたらまた新着情報として載せていきます。


【2014.09.19.2:50頃】
記事:MacOS向けのNativePluginを作成する
上記の記事の内容で使用と思ったんですけど、これだと、MacOS向けにしかできないんではないか疑惑があるので一時保留にします。
やはり5日前に書いた方法をちょっと試してみます。


【2014.10.03.14:20頃】
実は先日からすでに分かっていた事実なのですが、Unityの無料版ではC++を呼び出すのはできないらしいです。
少なくともデスクトップ上で動かすアプリケーションではできないらしいです...orz
下記の記事の中にサンプルコードがあるのですが、そちらを実行したところThis plugin is only supported in Unity Proと警告されました。
記事:Building Plugins for Desktop Platforms

また、下記の記事にはiOSでObjective-Cを動かすというサンプルコードがあるのですが、そちらのサンプルコード自体は動かせました。
記事:Building Plugins for iOS
しかし、同じ手順で作ったC++のプログラムはEntryPointNotFoundExceptionというエラーが表示されました。このエラー内容について調べたところ、下記の記事を発見しました。
記事:初心者がものすごく陥りやすかったUnity Native Plugin使用時のXcodeビルドエラー。
この記事の下部に書かれているのですが、

ちなみにUnity側で出ている「EntryPointNotFoundException:」はPC上でのプラグイン利用がUnity Proに限られることと関連してるぽい。

っとのこと...(^^;)
つまり、そうゆうことらしいです。

ただ、今までやってきたDLL化したものを呼び出すというのがMonoで作ったDLLなら使えるかもしれないので、ここについてはも少しいじってみようと思っています。
記事:Using Mono DLLs in a Unity Project
まぁ、結果は「Unity Proじゃないとサポートしないよー」だとは思いますが...。
うーん。Unity Pro準備するしか無いのかなぁ...。


3.結論

結局UnityFree版では出来ませんでした。UnityPro版のみC++のコードを呼び出すことに成功しました。Free版で実行すると「Unity Proじゃないとサポートしないよー」です。はい。
なので、C++で作ったコードを実装したい方はPro版の購入が必須です。
私は現在Pro版を利用して開発を行うようになったのですが、今での苦労がなんだったかのというくらい簡単にC++コードを扱えています。ただし、C++のコードはXcodeで作成し、必ず3ビルドするときは32bitでbundleを作成しなければならないので注意してください。また、あまりにもメモリを使うプログラムを作成するとオーバーフローしてしまいUnityがクラッシュしてしまいます。実はC++からPythonを操ってPythonで処理をした値をC++に渡してさらに処理を行うプログラムを作成したのですが、Pythonを扱うとかなりのメモリを食うらしくクラッシュしてしまいました。また、テキストデータの読み取りなどもテキストデータがあまりにも大きいと読み取りのさいにメモリを多く使いUnityがクラッシュしてしまいます。なので、テキストデータを読み取るのはUnityのC#側で行うのが無難だというのが自分の判断です(^^;)

BEST記事:Building Plugins for iOS


4.参考サイト・記事

  1. Unity C#でCのプラグインを使う際の問題あれこれ
  2. C#::マーシャル諸島
  3. unityでdylibが読み込めない問題
  4. c++ファイルのダイナミックライブラリdylibの作り方
  5. Unityでframeworkを読み込む
  6. Unity and DLLs: C# (managed) and C++ (unmanaged)

4.Unity関連の本

5.Unityで参考になるサイト・記事

その他にも多くの参考になるサイトや記事は多くあるので、日本語のサイトだけなく英語のサイトも参考にしてください。(というよりも、参考にさせて頂いています。お世話になっておりますm(_ _)m)

72
65
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
72
65

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?