Page 1 of 1

C# P/INVOKE for cpSpaceAddCollisionHandler

Posted: Sat Jun 18, 2016 1:07 am
by johnybe
Hello, I am trying to write a wrapper using C# and call the ChipmunkAPI. I can see that some things have changed in v7.0.1 and I am not sure how to integrate the 4 delegates needed for "begin", "preSolve", "postSolve" and "Separate" functions.

I am doing something like the following

Code: Select all

UIntPtr ptrForTypeA = new UIntPtr((ulong)typePair.a);
UIntPtr ptrForTypeB = new UIntPtr((ulong)typePair.b);

IntPtr collisionPtr = cpSpaceAddCollisionHandler(_handle, ptrForTypeA, ptrForTypeB);
cpCollisionHandler collisionHandler = (cpCollisionHandler)Marshal.PtrToStructure(collisionPtr, typeof(cpCollisionHandler));

and my cpCollisionHandler struct is 

private struct cpCollisionHandler {
			public UIntPtr typeA;
			public UIntPtr typeB;
			public IntPtr beginFunc;
			public IntPtr preSolveFunc;
			public IntPtr postSolveFunc;
			public IntPtr separateFunc;
			public IntPtr userData;
		}
The problem I have is that I am not sure how to bind the "beginFunc" function pointer to my C# function lets say the following

Code: Select all

public bool onBegin(IntPtr arb, IntPtr space, IntPtr userData){
  return false;
}
Any ideas?
Kind regards,
John.

Re: C# P/INVOKE for cpSpaceAddCollisionHandler

Posted: Sat Jun 18, 2016 2:12 pm
by slembcke
Hrm. It's been a few years since I've worked with PInvoke so I don't quite remember how C# delegates work with it anymore.

One definite problem I see is that you are using marshal to copy the cpCollisionHandler struct returned from cpSpaceAddCollisionHandler(). That won't work because you need to be able to set the delegates on the returned pointer, and not a copy.

Looking back at how we did it in ChipmunkUnity, we used Mono functions in order to invoke the callbacks since the old AOT version the used on mobile didn't allow generating trampoline functions for delegates. It looks like you are going to need to make some setter functions in C that take the handler struct and the right function pointer type. Easy, but tedious. At least there are only 4 of them I guess? In might be possible to do it straight in C# code, but I'm not really sure.

Re: C# P/INVOKE for cpSpaceAddCollisionHandler

Posted: Sat Jun 18, 2016 4:01 pm
by johnybe
It seems you are right, I noticed that Marshal was giving me a copy and I was just shooting in the air...
Now I am taking the collisionHandler directly by calling the cpSpaceAddCollisionHandler.

Code: Select all

CollisionHandler collisionHandler = cpSpaceAddCollisionHandler(_handle, ptrForTypeA, ptrForTypeB);
although I am not sure why the above code works (doesn't crash/ the compiler has no problem with it) as it returns an IntPtr and if I simply directly cast it to a struct like the following:

Code: Select all

private struct CollisionHandler {
 public IntPtr _handle;
}
I am in a dark terittory but after lots and lots of crashes and infinite loops I will be a better person :)

Yes, you are right, there are only 4 callback functions so I need to bind them with my C# delegates, I will try to do it as you suggest using C setter functions, I am not fluent in C but I think I can learn some more things :)