[NEWBIE] Plugin question
Per Bergman Lidebrandt
per.bergman at home.se
Mon Apr 14 11:20:35 UTC 2003
Hi all!
I'm exploring how to use existing libraries of C/C++ code within Squeak and my problem is about how to create oops directly on the plugin side and then return them to Squeak.
It's easy to return integer values created on the plugin side (if the values are within the 31-bit range). The integer value is stored in the oop header directly. Then we can use the convenient function 'integerObjectOf' for creating the oop from the plugin side:
:
/*The 'SmallInteger' oop*/
int _return_value;
_return_value = interpreterProxy->integerObjectOf(17);
interpreterProxy->popthenPush(1, _return_value);
But what about the other cases, when I want to return other 'primitive' data types created on the plugin side, which have their equivalence in Squeak, Strings, Arrays, etc. I've found out that the following code works for returning a native c-string, but I wonder, is there a more general, easier way of doing it, like the 'integerObjectOf(aCInteger) function?:
:
char* aCString;
int aStringOop;
char* aStringOopPtr;
/*The c-function I want to use from Squeak*/.
aCString = myCStringFunction();
/*Creation of the String object for the Squeak side, which is an oop pointing to its object header. "This operation does not execute initialization code typically associated
with the object class, however it merely allocates the space and initializes
all instance variables to nil.." (Greenberg)*/
aStringOop = interpreterProxy->instantiateClassindexableSize(interpreterProxy->classString(),
strlen(aCString));
/*C pointer to the first indexable oop stored in the
variable portion of the object 'aStringOop'*/
aStringOopPtr = ((char *) (interpreterProxy->firstIndexableField(aStringOop)));
/*Filling 'aStringOop' with the actual string value from 'aCString'*/
strcpy(aStringOopPtr, aCString);
/*Returning a String object to Squeak*/
interpreterProxy->popthenPush(1, aStringOop);
In the first 'round' I tried the 'TestInterpreterPlugin' for generating the c-code, easy and lazy ;-):
primCFunction
| aCString |
self var: #aCString declareC: 'char* aCString'.
self
primitive: 'primCFunction'
parameters: #()
receiver: #Oop.
aCString _ self cCode: 'myCFunction()'.
^ aCString asOop: String
It gave me this:
:
char* aCString;
int _return_value;
aCString = myCFunction();
_return_value = ((int) aCString) - 4;
interpreterProxy->popthenPush(1, _return_value);
But it didn't work (of course!). As I understand it, this assumes that 'aCString' points to the first indexable field in an oop and by reducing the pointer by 4 it would point to the oop header. Since the c-function just returns a plain c-pointer, which has no oop header, the result is that the returning oop just points to garbage.
So please enlight me on this matter!
Regards Per B. Lidebrandt
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20030414/ee410bc7/attachment.htm
More information about the Squeak-dev
mailing list
|