Passing strings to a plugin

David T. Lewis lewis at mail.msen.com
Sun Apr 2 13:35:37 UTC 2006


On Sun, Apr 02, 2006 at 02:02:41PM +0100, Bob.Cowdery at CGI-Europe.com wrote:
> 
> >> Either that or pass along their length.
> 
> Thanks Ragnar. Is there an easy was to null terminate a string in Squeak?

In the image you can of course do something like this:
    'hello', (Character value: 0) asString

If you want to pass a String parameter to your plugin then use it as
a C string, see the #cStringFromString and #transientCStringFromString:
methods in OSProcessPlugin (OSPP is on Squeak Map).

cStringFromString: aString
	"Answer a new null-terminated C string copied from aString. The C string
	is allocated from the C runtime heap. See transientCStringFromString for
	a version which allocates from object memory.
	Caution: This may invoke the garbage collector."

	| len sPtr cString |
	self returnTypeC: 'char *'.
	self var: 'sPtr' declareC: 'char *sPtr'.
	self var: 'cString' declareC: 'char *cString'.
	sPtr _ interpreterProxy arrayValueOf: aString.
	len _ interpreterProxy sizeOfSTArrayFromCPrimitive: sPtr.
	cString _ self callocWrapper: len + 1 size: 1.		"Space for a null terminated C string."
	self cCode: '(char *) strncpy (cString, sPtr, len)'.	"Copy the string."
	^ cString


transientCStringFromString: aString
	"Answer a new null-terminated C string copied from aString.
	The string is allocated in object memory, and will be moved
	without warning by the garbage collector. Any C pointer
	reference the the result is valid only until the garbage
	collector next runs. Therefore, this method should only be used
	within a single primitive in a section of code in which the
	garbage collector is guaranteed not to run. Note also that
	this method may itself invoke the garbage collector prior
	to allocating the new C string.

	Warning: The result of this method will be invalidated by the
	next garbage collection, including a GC triggered by creation
	of a new object within a primitive. Do not call this method
	twice to obtain two string pointers."

	| len stringPtr newString cString |
	self returnTypeC: 'char *'.
	self var: 'stringPtr' declareC: 'char *stringPtr'.
	self var: 'cString' declareC: 'char *cString'.
	len _ interpreterProxy sizeOfSTArrayFromCPrimitive: (interpreterProxy arrayValueOf: aString).
	"Allocate space for a null terminated C string."
	interpreterProxy pushRemappableOop: aString.
	newString _ interpreterProxy
		instantiateClass: interpreterProxy classString
		indexableSize: len + 1.
	stringPtr _ interpreterProxy arrayValueOf: interpreterProxy popRemappableOop.
	cString _ interpreterProxy arrayValueOf: newString.	"Point to the actual C string."
	self cCode: '(char *)strncpy(cString, stringPtr, len)'.	"Make a copy of the string."
	cString at: (len) put: 0.				"Null terminate the C string."
	^ cString


Dave




More information about the Squeak-dev mailing list