System.TypeInitializationException: An exception was thrown by the type initializer for SWIGExceptionHelper ---> System.EntryPointNotFoundException

StackOverflow https://stackoverflow.com/questions/23332554

  •  10-07-2023
  •  | 
  •  

Question

I seem to be traveling the road of trial and error that others before me have traveled in trying to get a new set of MonoMac bindings created. And like others, I've solved some things but ultimately am stuck.

At this point the bindings dll is created but when its consumed I get the error in the title of this thread. It looks like the key is the EntryPointNotFoundException. If I use the assembly browser in Xamarin Studio I see the DllImports look like this: [DllImport(, EntryPoint = )]. I'm not certain if the missing assembly name and entrypoint values are just due to it being an internal type and the browser won't show those. But that's one thing that sticks out...

The underlying library is native C++ and I've only been given the headers and the static library.a file. @Stephane Delcroix has an excellent post on how to generate bindings for MonoTouch (not MonoMac). And @poupou has a binding example for MonoMac but starting from Objective-C. What I've come up with for a makefile looks like this:

MONOMAC=/GitHub/MonoMac/src/MonoMac.dll
MCS=mcs
SWIG=swig
XBUILD=xcodebuild

CONFIGURATION=Release
LIB=libulapi.a
WRAPPER_PROJECT=ulapi_wrapper/ulapi_wrapper.xcodeproj
WRAPPER=libulapi_wrapper.a

all: UlApi.dll

debug: CONFIGURATION = Debug
debug: all

.SUFFIXES:
.SUFFIXES: .i .h .cs .mm

%.mm: %.i headers/ulfactory.h
    @mkdir -p generated
    $(SWIG) -c++ -csharp -namespace UlApi -dllimport __Internal -outdir generated -o $@  $<
    # Deal with reverse callbacks and fixup leading underscore on exports
    ruby fixup_generated_cs.rb generated/UlApiPINVOKE.cs > generated/UlApiPINVOKE_fixed.cs
    $(RM) generated/UlApiPINVOKE.cs
    mv generated/UlApiPINVOKE_fixed.cs generated/UlApiPINVOKE.cs

$(WRAPPER): ulapi.mm $(WRAPPER_PROJECT)
    # -sdk macosx
    $(XBUILD) -project $(WRAPPER_PROJECT) -target ulapi_wrapper -arch i386 -configuration $(CONFIGURATION) clean build
    -mv ulapi_wrapper/build/$(CONFIGURATION)/$(WRAPPER) $@

UlApi.dll: $(LIB) $(WRAPPER)
    $(MCS) -noconfig -o- -out:$@ -res:$(LIB) -res:$(WRAPPER) generated/*.cs -target:library -unsafe -r:System -r:System.Core -r:$(MONOMAC)

clean: 
    $(RM) $(WRAPPER) *.dll

clean-generated:
    $(RM) -r generated *.mm

clean-all: clean clean-generated

.PHONY: clean clean-all clean-generated

One change that wasn't obvious which I and others have learned is the "-arch i386" is needed in the xcodebuild. The default for the static library created in xcode was 64bit so changed it there as well. And once you target i386 you need to turn off ARC (you can actually build the dll targeting x86_64 and making sure to __bridge any (void *) casts of NSObjects in the mm file generated, but sounds like i386 is the way to go from what I've seen...including "MonoMac bindings have not been ported to 64 bits").

The other thing I had to do was that my static library wrapper project was being generated with leading underscores on the exports (discovered using "nm libulapi_wrapper.a". The output UlApiPINVOKE.cs file from Swig was mapping the EntryPoint to symbols that did not have the leading underscore. So I added more logic to the "fixup" ruby file to patch in that underscore.

It looks like there might be something yet to do with loading dylib's...see here and here but not sure exactly what.

Any suggestions welcome!

Was it helpful?

Solution

Eventually solved, special thanks to Brendan Zagaeski at Xamarin Support. Brendan wrote up the essence of the solution over here. This is the place to go for a start to finish explanation of the process.

Short summary of key not obvious parts in the solution:

  • The biggest problem in my case was even though the wrapper was being built i386, the source library was built for x64...doh! And the best source for this binding is via a dylib not a static archive.
  • Don't need to fixup callbacks like is done for iOS.
  • The wrapper library is created as a dylib also.
  • The dylib's are both loaded from the file system (not via embedded resources).
  • The "install name" path needs to be fixed up in order for the library to be located.
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top