我正在尝试使用 SWIG 将非托管 C++ 包装到我的 Xamarin.iOS 项目中。按照本教程,我已成功地将其包装到 C# 项目中: https ://stackoverflow.com/a/9816646/2494785
一旦我尝试合并 MonoTouch,一旦调用涉及我的 C++ 代码,我总是会遇到运行时错误。
我知道在将 SWIG 与 Monotouch 一起使用时需要进行一些细微的调整,但我一定遗漏了一些东西。我正在关注 Stephane 的博客http://blog.reblochon.org/2013/01/c-bindings-for-monotouch-using-swig.html#more作为参考。
我的 C#/Monotouch 项目之间的差异:
单触式
- 痛饮 -csharp -c++ -outdir myPath -dllimport __Internal cpp_file.i
然后我在我的 cppPINVOKE.cs 上运行这个ruby 脚本(由 James Moore 创建)
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#
- 痛饮 -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/ExceptionDelegate,cppPINVOKE/SWIGExceptionHelper/ExceptionDelegate ,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 在 StackOverFlowSwigWithXamarin.MyViewController。b__0 (System.Object sender, System.EventArgs e) [0x00001] 在 c:\Users\joshs\Documents\Visual Studio 2012\Projects\StackOverFlowSwigWithXamarin\StackOverFlowSwigWithXamarin\MyViewController.cs:38 在 MonoTouch.UIKit.UIControlEventProxy.Activated () [0x00000] 在 /Developer/MonoTouch/Source/monotouch/src/UIKit/UIControl.cs:30 处(包装器托管到本机) MonoTouch.UIKit.UIApplication: UIApplicationMain (int,string[],intptr,intptr) 在MonoTouch.UIKit.UIApplication.Main (System.String[] args, System.String principalClassName, System.String delegateClassName) [0x0004c] 在 /Developer/MonoTouch/Source/monotouch/src/UIKit/UIApplication.cs:3838 在 MonoTouch.UIKit.UIControlEventProxy.Activated () [0x00000] 在 /Developer/MonoTouch/Source/monotouch/src/UIKit/UIControl.cs:30 在 (wrapper managed-to-native) MonoTouch.UIKit.UIApplication: UIApplicationMain ( int,string[],intptr,intptr) 在 MonoTouch.UIKit.UIApplication.Main (System.String[] args, System.String principalClassName, System.String delegateClassName) [0x0004c] 在 /Developer/MonoTouch/Source/monotouch/src /UIKit/UIApplication.cs:3838 在 MonoTouch.UIKit.UIControlEventProxy.Activated () [0x00000] 在 /Developer/MonoTouch/Source/monotouch/src/UIKit/UIControl.cs:30 在 (wrapper managed-to-native) MonoTouch.UIKit.UIApplication: UIApplicationMain ( int,string[],intptr,intptr) 在 MonoTouch.UIKit.UIApplication.Main (System.String[] args, System.String principalClassName, System.String delegateClassName) [0x0004c] 在 /Developer/MonoTouch/Source/monotouch/src /UIKit/UIApplication.cs:38/Developer/MonoTouch/Source/monotouch/src/UIKit/UIApplication.cs:38 中的字符串 delegateClassName) [0x0004c]/Developer/MonoTouch/Source/monotouch/src/UIKit/UIApplication.cs:38 中的字符串 delegateClassName) [0x0004c]
在 StackOverFlowSwigWithXamarin.Application.Main (System.String[] args) [0x00001] 在 c:\Users\joshs\Documents\Visual Studio 2012\Projects\StackOverFlowSwigWithXamarin\StackOverFlowSwigWithXamarin\Main.cs:17 2013-10-31 14:45 :48.261 StackOverFlowSwigWithXamarin [13645:21e03] 未处理的托管异常:cpp_file..ctor () [0x00000] 在 c:\Users\joshs\Documents\Visual Studio 2012 中的 cppPINVOKE (System.TypeInitializationException) 的类型初始化程序引发了异常\Projects\StackOverFlowSwigWithXamarin\StackOverFlowSwigWithXamarin\Generated\cpp_file.cs:43 at StackOverFlowSwigWithXamarin.MyViewController.b__0 (System.Object sender, System.EventArgs e) [0x00001] in c:\Users\joshs\Documents\Visual Studio 2012\Projects\ StackOverFlowSwigWithXamarin\StackOverFlowSwigWithXamarin\MyViewController.cs:38 在 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) 在 MonoTouch.UIKit.UIApplication.Main (System.String [] args, System.String principalClassName, System.String delegateClassName) [0x0004c] 在 /Developer/MonoTouch/Source/monotouch/src/UIKit/UIApplication .cs:38 at StackOverFlowSwigWithXamarin.Application.Main (System.String[] args) [0x00001] 在 c:\Users\joshs\Documents\Visual Studio 2012\Projects\StackOverFlowSwigWithXamarin\StackOverFlowSwigWithXamarin\Main.cs:17 单声道:堆栈跟踪:UIKit.UIApplication:UIApplicationMain (int,string[],intptr,intptr) 在 MonoTouch.UIKit.UIApplication.Main (System.String[] args, System.String principalClassName, System.String delegateClassName) [0x0004c] 在 /Developer/MonoTouch /Source/monotouch/src/UIKit/UIApplication.cs:38 在 StackOverFlowSwigWithXamarin.Application.Main (System.String[] args) [0x00001] 在 c:\Users\joshs\Documents\Visual Studio 2012\Projects\StackOverFlowSwigWithXamarin\StackOverFlowSwigWithXamarin \Main.cs:17 单声道:堆栈跟踪:UIKit.UIApplication:UIApplicationMain (int,string[],intptr,intptr) 在 MonoTouch.UIKit.UIApplication.Main (System.String[] args, System.String principalClassName, System.String delegateClassName) [0x0004c] 在 /Developer/MonoTouch /Source/monotouch/src/UIKit/UIApplication.cs:38 在 StackOverFlowSwigWithXamarin.Application.Main (System.String[] args) [0x00001] 在 c:\Users\joshs\Documents\Visual Studio 2012\Projects\StackOverFlowSwigWithXamarin\StackOverFlowSwigWithXamarin \Main.cs:17 单声道:堆栈跟踪:C:\Users\joshs\Documents\Visual Studio 2012\Projects\StackOverFlowSwigWithXamarin\StackOverFlowSwigWithXamarin\Main.cs:17 中的主要(System.String[] args)[0x00001]:Stacktrace:C:\Users\joshs\Documents\Visual Studio 2012\Projects\StackOverFlowSwigWithXamarin\StackOverFlowSwigWithXamarin\Main.cs:17 中的主要(System.String[] args)[0x00001]:Stacktrace:
那么为什么我会得到这个异常,我该如何解决呢?
编辑(2013-11-1)我的(更多/更少)完整设置:
VS2012 StackOverFlowSwigWithXamarin.sln 包含两个项目
- cpp.vcxproj(C++ 项目)
- StackOverFlowSwigWithXamarin.csproj(从 VS 创建的 Xamarin iOS 项目(即没有 .xibs))
- Xamarin 项目是在 VS2012 文件 -> 新建 -> 项目... -> Visual C# -> iOS -> iPad -> HelloWorld 应用程序中制作的
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 中设置为自定义构建选项。它运行命令
痛饮 -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 项目
装配信息.cs
我注意到 Stephane 提到要添加[assembly: LinkWith(....)
,但我没有,因为我从未创建过 .lib/.a
自动生成的被添加到我的项目中:
- cpp.cs
- cpp_file.cs
- cppPINVOKE2.cs(来自上面提到的 ruby 脚本)
AppDelegate.cs、Main.cs
我对默认的 VS2012 -> iPad HelloWorldApplication 没有做任何更改
MyViewController.cs
我在默认的 HelloWorldApplication 中添加了一行。当用户按下屏幕上的按钮时,它会尝试实例化一个cpp_file()
.
我的顾虑
- 我从不碰 .cxx 文件。为什么会在那里?(也许这是我的问题的一部分)
- 从 Stephane 的博客中,他建议添加
[assembly: Linkwith(...)]
到我的 assemblyInfo.cs。我从来没有创建过图书馆,我应该有吗?如果有,是什么?