SWIG を使用してアンマネージ C++ を Xamarin.iOS プロジェクトにラップしようとしています。このチュートリアルに従って、C# プロジェクトにラップすることに成功しました: https://stackoverflow.com/a/9816646/2494785
MonoTouch を取り込もうとすると、C++ コードを含む呼び出しが行われるとすぐに、常に実行時エラーが発生します。
Monotouch で SWIG を使用する場合、微調整が必要であることは理解していますが、何かが欠けているに違いありません。私は Stephane のブログhttp://blog.reblochon.org/2013/01/c-bindings-for-monotouch-using-swig.html#moreを参照としてフォローしていました。
私の C#/Monotouch プロジェクトの違い:
モノタッチ
- swig -csharp -c++ -outdir myPath -dllimport __Internal cpp_file.i
次に、このRuby スクリプト (James Moore が作成) を cppPINVOKE.cs で実行します。
ARGF.each do |l| case l when /public delegate void Exception(Argument)?Delegate/ puts " [MonoTouch.MonoNativeFunctionWrapper]", l when /static void SetPendingArgument(Null|OutOfRange)?Exception/ puts " [MonoTouch.MonoPInvokeCallback (typeof (ExceptionArgumentDelegate))]", l when /static void SetPending.*Exception/ puts " [MonoTouch.MonoPInvokeCallback (typeof (ExceptionDelegate))]", l when /static string CreateString/ puts " [MonoTouch.MonoPInvokeCallback (typeof (SWIGStringDelegate))]", l else puts l end end
C#
- swig -csharp -c++ -outdir myPath cpp_file.i
プロジェクトを実行しようとしたときに発生する例外は次のとおりです。
未処理の例外:
System.TypeInitializationException: cppPINVOKE の型初期化子によって例外がスローされました
未処理の例外: System.TypeInitializationException: cppPINVOKE の型初期化子によって例外がスローされました ---> System.TypeInitializationException: SWIGExceptionHelper の型初期化子によって例外がスローされました ---> System.EntryPointNotFoundException: SWIGRegisterExceptionCallbacks_cpp at (wrapper managed-to -native) cppPINVOKE/SWIGExceptionHelper:SWIGRegisterExceptionCallbacks_cpp (cppPINVOKE/SWIGExceptionHelper/ExceptionDelegate、cppPINVOKE/SWIGExceptionHelper/ExceptionDelegate、cppPINVOKE/SWIGExceptionHelper/ExceptionDelegate、cppPINVOKE/SWIGExceptionHelper/ExceptionDelegate、cppPINVOKE/SWIGExceptionHelper/ExceptionDelegate、cppPINVOKE/SWIGExceptionHelper/SWIGExceptionHelperExceptionDelegate、cppPINVOKE/SWIGExceptionHelperExceptionDelegate ,cppPINVOKE/SWIGExceptionHelper/ExceptionDelegate,cppPINVOKE/SWIGExceptionHelper/ExceptionDelegate、cppPINVOKE/SWIGExceptionHelper/ExceptionDelegate、cppPINVOKE/SWIGExceptionHelper/ExceptionDelegate) c:\Users\joshs\Documents\Visual Studio 2012\Projects\StackOverFlowSwigWithXamarin\StackOverFlowSwigWithXamarin\ の cppPINVOKE+SWIGExceptionHelper..cctor () [0x000ef] でGenerated\cppPINVOKE2.cs:121 --- 内部例外スタック トレースの終わり --- c:\Users\joshs\Documents\Visual Studio 2012\Projects\StackOverFlowSwigWithXamarin\StackOverFlowSwigWithXamarin\Generated の cppPINVOKE..cctor () [0x00000] で\cppPINVOKE2.cs:141 --- 内部例外スタック トレースの終了 --- c:\Users\joshs\Documents\Visual Studio 2012\Projects\StackOverFlowSwigWithXamarin\StackOverFlowSwigWithXamarin\Generated\ の cpp_file..ctor () [0x00000] cpp_file.cs:43 at StackOverFlowSwigWithXamarin.MyViewController.b__0 (System.Object 送信者、System.EventArgs e) [0x00001] in c:\Users\joshs\Documents\Visual Studio 2012\Projects\StackOverFlowSwigWithXamarin\StackOverFlowSwigWithXamarin\MyViewController.cs:38 at MonoTouch.UIKit.UIControlEventProxy.Activated () [0x00000] in /Developer/MonoTouch/Source/monotouch/src/UIKit/UIControl.cs:30 at (wrapper managed-to-native) MonoTouch.UIKit.UIApplication: UIApplicationMain (int,string[],intptr,intptr) at MonoTouch.UIKit.UIApplication.Main (System.String[] args、System.String principalClassName、System.String delegateClassName) [0x0004c] in /Developer/MonoTouch/Source/monotouch/src/UIKit/UIApplication.cs:3838 at MonoTouch.UIKit.UIControlEventProxy.Activated () [0x00000] in /Developer/MonoTouch/Source/monotouch/src/UIKit/UIControl.cs:30 at (wrapper managed-to-native) MonoTouch.UIKit.UIApplication: UIApplicationMain ( /Developer/MonoTouch/Source/monotouch/src の MonoTouch.UIKit.UIApplication.Main (System.String[] args、System.String principalClassName、System.String delegateClassName) [0x0004c] の int,string[],intptr,intptr) /UIKit/UIApplication.cs:3838 at MonoTouch.UIKit.UIControlEventProxy.Activated () [0x00000] in /Developer/MonoTouch/Source/monotouch/src/UIKit/UIControl.cs:30 at (wrapper managed-to-native) MonoTouch.UIKit.UIApplication: UIApplicationMain ( /Developer/MonoTouch/Source/monotouch/src の MonoTouch.UIKit.UIApplication.Main (System.String[] args、System.String principalClassName、System.String delegateClassName) [0x0004c] の int,string[],intptr,intptr) /UIKit/UIApplication.cs:38String delegateClassName) [0x0004c] in /Developer/MonoTouch/Source/monotouch/src/UIKit/UIApplication.cs:38String delegateClassName) [0x0004c] in /Developer/MonoTouch/Source/monotouch/src/UIKit/UIApplication.cs:38
c:\Users\joshs\Documents\Visual Studio 2012\Projects\StackOverFlowSwigWithXamarin\StackOverFlowSwigWithXamarin\Main.cs:17 2013-10-31 14:45 の StackOverFlowSwigWithXamarin.Application.Main (System.String [] args) [0x00001] で:48.261 StackOverFlowSwigWithXamarin[13645:21e03] 未処理のマネージ例外: c:\Users\joshs\Documents\Visual Studio 2012 の cpp_file..ctor () [0x00000] で cppPINVOKE (System.TypeInitializationException) の型初期化子によって例外がスローされました\Projects\StackOverFlowSwigWithXamarin\StackOverFlowSwigWithXamarin\Generated\cpp_file.cs:43 at StackOverFlowSwigWithXamarin.MyViewController.b__0 (System.Object 送信者、System.EventArgs e) [0x00001] c:\Users\joshs\Documents\Visual Studio 2012\Projects\ StackOverFlowSwigWithXamarin\StackOverFlowSwigWithXamarin\MyViewController.cs:38 (モノタッチ)。UIKit.UIControlEventProxy.Activated () [0x00000] in /Developer/MonoTouch/Source/monotouch/src/UIKit/UIControl.cs:30 at (wrapper managed-to-native) MonoTouch.UIKit.UIApplication:UIApplicationMain (int,string[ ],intptr,intptr) /Developer/MonoTouch/Source/monotouch/src/UIKit/UIApplication の MonoTouch.UIKit.UIApplication.Main (System.String[] args, System.String principalClassName, System.String delegateClassName) [0x0004c] でc:\Users\joshs\Documents\Visual Studio 2012\Projects\StackOverFlowSwigWithXamarin\StackOverFlowSwigWithXamarin\Main.cs:17 の StackOverFlowSwigWithXamarin.Application.Main (System.String[] args) [0x00001] の .cs:38:スタックトレース:UIKit.UIApplication:UIApplicationMain (int,string[],intptr,intptr) at MonoTouch.UIKit.UIApplication.Main (System.String[] args, System.String principalClassName, System.String delegateClassName) [0x0004c] in /Developer/ MonoTouch /Source/monotouch/src/UIKit/UIApplication.cs:38 at StackOverFlowSwigWithXamarin.Application.Main (System.String[] args) [0x00001] in c:\Users\joshs\Documents\Visual Studio 2012\Projects\StackOverFlowSwigWithXamarin\StackOverFlowSwigWithXamarin \Main.cs:17 mono-rt: スタックトレース:UIKit.UIApplication:UIApplicationMain (int,string[],intptr,intptr) at MonoTouch.UIKit.UIApplication.Main (System.String[] args, System.String principalClassName, System.String delegateClassName) [0x0004c] in /Developer/ MonoTouch /Source/monotouch/src/UIKit/UIApplication.cs:38 at StackOverFlowSwigWithXamarin.Application.Main (System.String[] args) [0x00001] in c:\Users\joshs\Documents\Visual Studio 2012\Projects\StackOverFlowSwigWithXamarin\StackOverFlowSwigWithXamarin \Main.cs:17 mono-rt: スタックトレース:Main (System.String[] args) [0x00001] in c:\Users\joshs\Documents\Visual Studio 2012\Projects\StackOverFlowSwigWithXamarin\StackOverFlowSwigWithXamarin\Main.cs:17 mono-rt: Stacktrace:Main (System.String[] args) [0x00001] in c:\Users\joshs\Documents\Visual Studio 2012\Projects\StackOverFlowSwigWithXamarin\StackOverFlowSwigWithXamarin\Main.cs:17 mono-rt: Stacktrace:
では、なぜこの例外が発生するのですか?どうすれば修正できますか?
編集 (2013-11-1) 私の (多かれ少なかれ) 完全なセットアップ:
VS2012 StackOverFlowSwigWithXamarin.sln には 2 つのプロジェクトが含まれています
- cpp.vcxproj (C++ プロジェクト)
- StackOverFlowSwigWithXamarin.csproj (VS から作成された Xamarin iOS プロジェクト (つまり、.xibs なし))
- Xamarin プロジェクトは VS2012 で作成されました File -> New -> Project... -> Visual C# -> iOS -> iPad -> HelloWorld Application
cppプロジェクト
cpp_file.h
#pragma once
#ifdef cpp_EXPORTS
#define cpp_API __declspec(dllexport)
#else
#define cpp_API __declspec(dllimport)
#endif
class cpp_API cpp_file
{
public:
cpp_file(void);
~cpp_file(void);
int times2(int arg);
};
cpp_file.cpp
#include "cpp_file.h"
cpp_file::cpp_file(void)
{
}
cpp_file::~cpp_file(void)
{
}
int cpp_file::times2(int arg)
{
return arg * 2;
}
cpp_file.i
%module cpp
%{
#include "cpp_file.h"
%}
%include <windows.i>
%include "cpp_file.h"
cpp_file.i ファイルは、VS2012内でカスタム ビルドオプションとして設定されます。コマンドを実行します
swig -csharp -c++ -outdir "$(SolutionDir)StackOverFlowSwigWithXamarin\Generated" cpp_file.i
カスタム ビルド ツールからの出力は、次のように指定されます。
cpp_file_wrap.cxx
....しかし、私はこのファイルを使用したことがありません。何のためにあるのかわかりません。
cpp プロジェクトをビルドすると、次のファイルが生成されます。
- cpp_file_wrap.cxx
- cpp.cs
- cpp_file.cs
- cppPINVOKE.cs
その後、Ruby スクリプトを実行して、cppPINVOKE2.csという名前の新しいファイルを作成します。
StackOverFlowSwigWithXamarin プロジェクト
AssemblyInfo.cs
Stephane が を追加するように言及していることに気付き[assembly: LinkWith(....)
ましたが、.lib/.a を作成したことがないため、追加しませんでした。
自動生成されたものが私のプロジェクトに追加されます:
- cpp.cs
- cpp_file.cs
- cppPINVOKE2.cs (上記の ruby スクリプトから)
AppDelegate.cs、Main.cs
デフォルトの VS2012 に変更を加えていません -> iPad HelloWorldApplication
MyViewController.cs
デフォルトの HelloWorldApplication に 1 行追加しました。ユーザーが画面上のボタンを押すと、cpp_file()
.
私の懸念
- .cxx ファイルには触れません。なぜそこにあるのですか?(多分それは私の問題の一部です)
- Stephane のブログから、彼は
[assembly: Linkwith(...)]
私の assemblyInfo.cs に追加することを勧めています。ライブラリを作成したことがありません。作成する必要がありますか? もしそうなら、何の?