What should be simple has turned into a convoluted mess of ugliness. So here’s the story. I downloaded the awesome Box2D, took out the important c++ files and added an interface for SWIG. I then proceeded to create the Swig wrapper by using a makefile
CC=g++
CFLAGS=-c -Wall -fPIC -I../
LDFLAGS=-shared -o box.dll
SOURCES=<OMITTED>
OBJECTS=$(SOURCES:.cpp=.o)
EXECUTABLE=box2d.dll
all: $(SOURCES) $(EXECUTABLE)
$(EXECUTABLE): $(OBJECTS)
$(CC) $(LDFLAGS) $(OBJECTS) -o $@
.cpp.o:
$(CC) $(CFLAGS) $< -o $@
swig:
swig -csharp -c++ -outdir Wrapper Box2D.i
clean:
-rm Collision/*.o
-rm Collision/Shapes/*.o
-rm Common/*.o
-rm Dynamics/*.o
-rm Dynamics/Contacts/*.o
-rm Dynamics/Joints/*.o
-rm Rope/*.o
Pretty normal stuff, and it works fine (After fixing %includes and not #includes in the interface file). So I “make swig” in cygwin, no problems there (had to re-order includes so base classes came first). Then I loaded it up in VS.NET 2012, copying all the wrapper .cs files into the solution and moving the DLL over. This is where it gets nasty.
First time round, I believe it was mixed x86 and x64 that was causing great issue. I could instantly see that this was the problem and was in no way confused by the highly descriptive error message:
System.BadImageFormatException: An attempt was made to load a program with an incorrect format. (Exception from HRESULT: 0x8007000B)
In my attempts to fix this, much of the Googling resolved that perhaps the calling convention was the culprate, so I changed the SWIG wrapper cpp file to export the functions into the dll as __cdecl rather than __stdcall, and updated the wrapper appropriately.
Anyway so I eventually fixed the x86/x64 mixing by making a new x86 build profile, and then upon calling any function in the dll, the program just hanged. So I decided to revert back to basics and simply compile with __stdcall, no wrapper mods, and just see if it would work.
It didn’t.
Now it complains that it’s missing entry points:
{"Unable to find an entry point named 'SWIGRegisterExceptionCallbacks_box2d' in DLL 'box2d'.":""} System.Exception {System.EntryPointNotFoundException}
Upon dumping the exports of the DLL, the functions are correctly mangled according to __stdcall
CSharp_b2_aabbMultiplier_get@0
...
SWIGRegisterStringCallback_box2d@4
SWIGRegisterExceptionCallbacks_box2d@44
etc. etc.
Now the C# wrapper end doesn’t seem to find this a problem and goes straight ahead and ignores the mangling
[DllImport("box2d", EntryPoint="SWIGRegisterExceptionArgumentCallbacks_box2d")]
So I tried this out of desperation
[DllImport("box2d", EntryPoint = "SWIGRegisterExceptionCallbacks_box2d", CallingConvention = CallingConvention.StdCall)]
Which was met with the same problem. The solution? Stick the mangled name in.
[DllImport("box2d", EntryPoint="SWIGRegisterExceptionArgumentCallbacks_box2d@44")]
… for all 1392 DllImport attributes. Not a solution.
I’ve tried compiling DLLs with both minGW and Cygwin, so I doubt that the way the DLLs are compiled is much of an issue.
Does anybody have any idea what I’m doing wrong?
So it turns out that C# cannot into Cygwin or MinGW dlls, so I recompiled with VSC++ and everything went fine.