2

我正在尝试使用 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。我从来没有创建过图书馆,我应该有吗?如果有,是什么?
4

0 回答 0