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