Begin forwarded message:
From: Joachim Geidel joachim.geidel@onlinehome.de Date: May 15, 2010 10:57:37 PM GMT+02:00 To: pharo-users@lists.gforge.inria.fr Subject: [Pharo-users] Need help with Alien, unexpected function return value Reply-To: A friendly place where any question about pharo is welcome pharo-users@lists.gforge.inria.fr
Hello everybody,
I need some help with Alien on Mac OS X 10.6.3 in Pharo 1.0. I am calling a function from a vtable struct in the Java Native Interface of the Java VM which comes with Mac OS X and which is defined as
jint ( __stdcall * GetVersion)(JNIEnv * env);
The result type jint is just an alias for int. The Smalltalk method is
primGetVersion | functionPointer result vtablePointer | vtablePointer := Alien atAddress: self externalData asUnsignedLong dataSize: Alien sizeofPointer * self vtableSize. functionPointer := Alien forPointer: (vtablePointer unsignedLongAt: (4 * Alien sizeofPointer + 1)). result := (Alien newGC: 4) pointer. functionPointer primFFICallResult: result with: self asJNIParameter. ^result signedIntAt: 1
functionPointer is the pointer to the GetVersion function. The result should be 65542 (16r00010006), which is also what I get when calling the function from VisualWorks, but the method answers -394042288 (-16r177C9BB0). The "result" Alien has the printString '#[0 0 0 0 6 0 1 0]' which suspiciously contains the 1 and the 6 I am looking for, but in the wrong places. ;-)
I looked at examples for callouts, which seem to indicate that result should be the Alien and not a pointer to it. So I changed the code to
result := (Alien newC: 4). functionPointer primFFICallResult: result pointer with: self asJNIParameter. ^result signedIntAt: 1
This didn't really help. The result is now 0 (zero), although the Alien prints as #[252 255 255 255 80 15 38 0] which doesn't look like a 0 at first sight.
Am I using those Aliens in a correct way? What can I try to debug this? If this is too obscure and someone who knows about Aliens would like to have a look at the rest of the code, I am willing to send a bunch of Monticello packages and instructions for reproducing the problem, but I won't make it publicly available yet.
Any help is welcome.
Best regards, Joachim Geidel
-- View this message in context: http://forum.world.st/Need-help-with-Alien-unexpected-function-return-value-... Sent from the Pharo Smalltalk Users mailing list archive at Nabble.com.
Pharo-users mailing list Pharo-users@lists.gforge.inria.fr http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-users
Hi Joachim,
On 15/05/2010 22:16, stephane ducasse wrote:
From: Joachim Geidel joachim.geidel@onlinehome.de
Date: May 15, 2010 10:57:37 PM GMT+02:00 To: pharo-users@lists.gforge.inria.fr Subject: [Pharo-users] Need help with Alien, unexpected function return value Reply-To: A friendly place where any question about pharo is welcomepharo-users@lists.gforge.inria.fr
Hello everybody,
I need some help with Alien on Mac OS X 10.6.3 in Pharo 1.0. I am calling a function from a vtable struct in the Java Native Interface of the Java VM which comes with Mac OS X and which is defined as
jint ( __stdcall * GetVersion)(JNIEnv * env);
The result type jint is just an alias for int. The Smalltalk method is
primGetVersion | functionPointer result vtablePointer | vtablePointer := Alien atAddress: self externalData asUnsignedLong dataSize: Alien sizeofPointer * self vtableSize. functionPointer := Alien forPointer: (vtablePointer unsignedLongAt: (4 * Alien sizeofPointer + 1)). result := (Alien newGC: 4) pointer. functionPointer primFFICallResult: result with: self asJNIParameter. ^result signedIntAt: 1
functionPointer is the pointer to the GetVersion function. The result should be 65542 (16r00010006), which is also what I get when calling the function from VisualWorks, but the method answers -394042288 (-16r177C9BB0). The "result" Alien has the printString '#[0 0 0 0 6 0 1 0]' which suspiciously contains the 1 and the 6 I am looking for, but in the wrong places. ;-)
When you use a pointer alien (which has a size field of zero) as the return result of a function call, the alien code expects the result from the alien to be a pointer to some area of memory and replaces the address field of the result alien with the result returned by the function call. You're lucky your method returned any result at all rather than crashing with an access violation - you are dereferencing whatever sits at 0x00010006.
I looked at examples for callouts, which seem to indicate that result should be the Alien and not a pointer to it. So I changed the code to
result := (Alien newC: 4). functionPointer primFFICallResult: result pointer with: self asJNIParameter. ^result signedIntAt: 1
This didn't really help. The result is now 0 (zero), although the Alien prints as #[252 255 255 255 80 15 38 0] which doesn't look like a 0 at first sight.
This time you are returning the signed int at the block of memory allocated by the newC: call. The memory gets zeroed before use, which is why you get a zero. Because you used "result pointer" in the alien call the alien code again replaces the pointer alien's address with the result. This time though, you don't have a reference to the pointer alien, so the result is effectively discarded.
Try the following
result := (Alien new: 4). functionPointer primFFICallResult: result with: self asJNIParameter. ^result signedIntAt: 1
Note that I could have used a C alloc'ed alien here, but there is no need.
HTH
Regards, Steve
vm-dev@lists.squeakfoundation.org