Thanks Dave, it works. ...its...hum... not straighforward! :)
I'll finnish to debug and clean the code tomorrow, and I hope to be able to quickly release a patch.
What's the procedure to get the patch reviewed and possibly included in the trunk (including the OLPC Etoys branch)?
Bye, Séverin
On Mon, Jan 5, 2009 at 00:46, David T. Lewis lewis@mail.msen.com wrote:
On Sun, Jan 04, 2009 at 11:54:22PM +0100, S??verin Lemaignan wrote:
For each of them, I need to get the port name. I did like that (copy-pasted from another plugin):
int spName; char * spNameIndex; spName = interpreterProxy->stackValue(0); interpreterProxy->success(interpreterProxy->isBytes(spName)); spNameIndex = interpreterProxy->firstIndexableField(spName);
But I probably do something wrong since if I call the primitive "primSerialPortOpenByName" with "/dev/ttyACM0" as port name from Squeak, the plugin code in sqUnixSerial.c receives a different string ("/dev/ttyACM0_?????? @???w @???w "), thus failing to open the serial port.
Does someone knows how to correctly transmit a string argument to a plugin?
S??verin,
The trick here is that C expects strings to be null-terminated, and the Squeak string that you pass to the primitive does not have the trailing null.
In general, you will want to copy the Squeak string contents into a freshly allocated char[] array of size one greater than the string length. There are a number of ways you can do this, but to give some examples you can look in OSProcessPlugin (available on SqueakSource in project OSProcessPlugin). The methods #transientCStringFromString: and #cStringFromString: provide two ways to do the conversion. As an example, here is a primitive from UnixOSProcessPlugin after it has been converted from Slang to C:
/* Call chdir(2) to change current working directory to the specified path string. Answer nil for success, or errno on failure. */
EXPORT(sqInt) primitiveChdir(void) { extern int errno; char * path; sqInt aString; sqInt len; char *cString; char *stringPtr; sqInt newString;
/* begin transientCStringFromString: */ aString = interpreterProxy->stackObjectValue(0); len = interpreterProxy->sizeOfSTArrayFromCPrimitive(interpreterProxy->arrayValueOf(aString)); interpreterProxy->pushRemappableOop(aString); newString = interpreterProxy->instantiateClassindexableSize(interpreterProxy->classString(), len + 1); stringPtr = interpreterProxy->arrayValueOf(interpreterProxy->popRemappableOop()); cString = interpreterProxy->arrayValueOf(newString); (char *)strncpy(cString, stringPtr, len); cString[len] = 0; path = cString; if (chdir(path)) { interpreterProxy->pop(2); interpreterProxy->push(interpreterProxy->nilObject()); } else { interpreterProxy->pop(2); interpreterProxy->pushInteger(errno); }
}
And by the way, happy new year to everybody!
And to you as well!
- Dave