title: SWIG, Box2D, and C#
body: <p>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</p>
  
  <pre><code>CC=g++
  CFLAGS=-c -Wall -fPIC -I../
  LDFLAGS=-shared -o box.dll
  SOURCES=&lt;OMITTED&gt;
  
  OBJECTS=$(SOURCES:.cpp=.o)
  EXECUTABLE=box2d.dll
  
  all: $(SOURCES) $(EXECUTABLE)
  
  $(EXECUTABLE): $(OBJECTS) 
      $(CC) $(LDFLAGS) $(OBJECTS) -o $@
  
  .cpp.o:
      $(CC) $(CFLAGS) $&lt; -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
  </code></pre>
  
  <p>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.</p>
  
  <p>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:</p>
  
  <pre><code>System.BadImageFormatException: An attempt was made to load a program with an incorrect format. (Exception from HRESULT: 0x8007000B)
  </code></pre>
  
  <p>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.</p>
  
  <p>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. </p>
  
  <p>It didn't. </p>
  
  <p>Now it complains that it's missing entry points:</p>
  
  <pre><code>{"Unable to find an entry point named 'SWIGRegisterExceptionCallbacks_box2d' in DLL 'box2d'.":""} System.Exception {System.EntryPointNotFoundException}
  </code></pre>
  
  <p>Upon dumping the exports of the DLL, the functions are correctly mangled according to __stdcall</p>
  
  <pre><code>CSharp_b2_aabbMultiplier_get@0
  ...
  SWIGRegisterStringCallback_box2d@4
  SWIGRegisterExceptionCallbacks_box2d@44
  </code></pre>
  
  <p>etc. etc.</p>
  
  <p>Now the C# wrapper end doesn't seem to find this a problem and goes straight ahead and ignores the mangling</p>
  
  <pre><code>[DllImport("box2d", EntryPoint="SWIGRegisterExceptionArgumentCallbacks_box2d")]
  </code></pre>
  
  <p>So I tried this out of desperation</p>
  
  <pre><code>[DllImport("box2d", EntryPoint = "SWIGRegisterExceptionCallbacks_box2d", CallingConvention = CallingConvention.StdCall)]
  </code></pre>
  
  <p>Which was met with the same problem. The solution? Stick the mangled name in.</p>
  
  <pre><code>[DllImport("box2d", EntryPoint="SWIGRegisterExceptionArgumentCallbacks_box2d@44")]
  </code></pre>
  
  <p>... for all 1392 DllImport attributes. Not a solution. </p>
  
  <p>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.</p>
  
  <p>Does anybody have any idea what I'm doing wrong?</p>