2

I'm trying to use SWIG to wrap unmanaged C++ into my Xamarin.iOS project. I've successfully wrapped it into a C# project following this tutorial: https://stackoverflow.com/a/9816646/2494785

Once I try to incorporate MonoTouch, I always get run-time errors as soon as a call is made involving my C++ code.

I understand minor tweaks need to be made when using SWIG with Monotouch, but I must be missing something. I was following Stephane's blog http://blog.reblochon.org/2013/01/c-bindings-for-monotouch-using-swig.html#more as a reference.

Differences between my C#/Monotouch projects:

Monotouch

  • swig -csharp -c++ -outdir myPath -dllimport __Internal cpp_file.i
  • I then run this ruby script (created by James Moore) on my 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

Here's the exception I get when I try to run my project:

Unhandled Exception:

System.TypeInitializationException: An exception was thrown by the type initializer for cppPINVOKE

Unhandled Exception: System.TypeInitializationException: An exception was thrown by the type initializer for cppPINVOKE ---> System.TypeInitializationException: An exception was thrown by the type initializer for 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) at cppPINVOKE+SWIGExceptionHelper..cctor () [0x000ef] in c:\Users\joshs\ Documents\Visual Studio 2012\Projects\StackOverFlowSwigWithXamarin\StackOverFlowSwigWithXamarin\Generated\cppPINVOKE2.cs:121 --- End of inner exception stack trace --- at cppPINVOKE..cctor () [0x00000] in c:\Users\joshs\Documents\Visual Studio 2012\Projects\StackOverFlowSwigWithXamarin\StackOverFlowSwigWithXamarin\Generated\cppPINVOKE2.cs:141 --- End of inner exception stack trace --- at cpp_file..ctor () [0x00000] in c:\Users\joshs\Documents\Visual Studio 2012\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 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:38
at StackOverFlowSwigWithXamarin.Application.Main (System.String[] args) [0x00001] in c:\Users\joshs\Documents\Visual Studio 2012\Projects\StackOverFlowSwigWithXamarin\StackOverFlowSwigWithXamarin\Main.cs:17 2013-10-31 14:45:48.261 StackOverFlowSwigWithXamarin[13645:21e03] Unhandled managed exception: An exception was thrown by the type initializer for cppPINVOKE (System.TypeInitializationException) at cpp_file..ctor () [0x00000] in c:\Users\joshs\Documents\Visual Studio 2012\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 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: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: Stacktrace:

So why am I getting this exception and how can I fix it?


Edit (2013-11-1) My (more/less) complete setup:

VS2012 StackOverFlowSwigWithXamarin.sln contains two projects

  • cpp.vcxproj (C++ project)
  • StackOverFlowSwigWithXamarin.csproj (Xamarin iOS project created from VS (i.e. No .xibs))
    • The Xamarin project was made in VS2012 File -> New -> Project... -> Visual C# -> iOS -> iPad -> HelloWorld Application

cpp Project

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"

The cpp_file.i file is set as a custom build option within VS2012. It runs the command

swig -csharp -c++ -outdir "$(SolutionDir)StackOverFlowSwigWithXamarin\Generated" cpp_file.i

The outputs from the custom build tool is specified as:

cpp_file_wrap.cxx

....but I never use this file, I have no idea what it's there for?

Building my cpp Project produces the following files:

  • cpp_file_wrap.cxx
  • cpp.cs
  • cpp_file.cs
  • cppPINVOKE.cs

Afterwards, I run my ruby script to create a new file I named cppPINVOKE2.cs

StackOverFlowSwigWithXamarin Project

AssemblyInfo.cs

I noticed Stephane mentioned to add [assembly: LinkWith(....), but I did not, because I never created a .lib/.a

The autogenerated are added to my project:

  • cpp.cs
  • cpp_file.cs
  • cppPINVOKE2.cs (from the ruby script, mentioned above)

AppDelegate.cs, Main.cs

I made no changes to the default VS2012 -> iPad HelloWorldApplication

MyViewController.cs

I added one line to the default HelloWorldApplication. When the user presses the button on the screen, it tries to instantiate a cpp_file().

My Concerns

  • I never touch the .cxx file. Why is it there? (Maybe that's part of my problem)
  • From Stephane's blog, he recommends to add [assembly: Linkwith(...)] to my assemblyInfo.cs. I never created a library, should I have? If so, of what?
Community
  • 1
  • 1
Josh Schultz
  • 897
  • 1
  • 13
  • 32
  • you might have to share a bit more, like the project files – Stephane Delcroix Nov 01 '13 at 07:29
  • I added quite a bit about my setup, as stated in my edit, I'm wondering if my problem is part of not using the autogenerated .cxx file and/or never creating some sort of library. – Josh Schultz Nov 01 '13 at 16:08
  • yeah, you should create a library from your objective-cpp project generated. that's a crucial part of the process – Stephane Delcroix Nov 01 '13 at 21:55
  • Excuse me of my lack of understanding, but do you add the C++ header files, the generated .mm file, and then custom make an Obj-C header? ...to the Obj-C static library, or is adding the C++ headers and .mm file all that is required to build the .a static library? – Josh Schultz Nov 21 '13 at 21:50

0 Answers0