Passing a char[] inside a struct to an FFI call
C. David Shaffer
cdshaffer at acm.org
Fri Dec 10 21:51:48 UTC 2004
Hi folks,
I'm stumped on an FFI issue. I want to allocate and send a:
typedef struct {
int someNumber;
char someString[255];
} MyStruct;
into:
int printIt(MyStruct* s, int size);
So I declare an ExternalStructure subclass and specify fields on the
class side as:
fields
"self defineFields"
^#((someNumber 'long') (someString 'ExternalData' 255))
and
apiPrintIt: me size: size
<cdecl: long 'printIt' (SCExampleStruct* long) module: 'ffiexample'>
^self externalCallFailed
but the generated mutator for someString doesn't copy all 255 bytes of
my string. That is, it looks like:
someString: anObject
"This method was automatically generated"
handle structAt: 5 put: anObject getHandle length: 4.
My printIt method shows the first 4 bytes of the string but, as
expected, doesn't get the rest right. I overrode class side byteSize to
return 259 (255+4) but that didn't help. I hate to change this method
since it was automatically generated and I don't understand the
concequences of such a change. How should I really go about this?
I have attached my code (for curious, helpful or insanely bored). Some
hints would be helpful. I've read many of the e-mails on this list
about FFI but I'm not making progress quickly enough. Here's my workspace:
s _ SCExampleStruct new.
s someNumber: 10.
s someString: ('hhhhhhhhellllllo world' asExternalCString: 255).
s printMe
Lost and confused,
David
--
C. David Shaffer
http://www.cs.westminster.edu/~shaffer
http://www.shaffer-consulting.com
-------------- next part --------------
'From Squeak3.7 of ''4 September 2004'' [latest update: #5989] on 10 December 2004 at 4:49:04 pm'!
ExternalStructure subclass: #SCExampleStruct
instanceVariableNames: ''
classVariableNames: ''
poolDictionaries: ''
category: 'PalmPilot'!
!SCExampleStruct methodsFor: 'accessing' stamp: 'cds 12/10/2004 16:37'!
someNumber
"This method was automatically generated"
^handle signedLongAt: 1! !
!SCExampleStruct methodsFor: 'accessing' stamp: 'cds 12/10/2004 16:37'!
someNumber: anObject
"This method was automatically generated"
handle signedLongAt: 1 put: anObject! !
!SCExampleStruct methodsFor: 'accessing' stamp: 'cds 12/10/2004 16:37'!
someString
"This method was automatically generated"
^ExternalData fromHandle: (handle structAt: 5 length: 4)! !
!SCExampleStruct methodsFor: 'accessing' stamp: 'cds 12/10/2004 16:37'!
someString: anObject
"This method was automatically generated"
handle structAt: 5 put: anObject getHandle length: 4.! !
!SCExampleStruct methodsFor: 'apicalls' stamp: 'cds 12/10/2004 12:27'!
apiPrintIt: me size: size
<cdecl: long 'printIt' (SCExampleStruct* long) module: 'ffiexample'>
^self externalCallFailed ! !
!SCExampleStruct methodsFor: 'api' stamp: 'cds 12/10/2004 12:28'!
printMe
self apiPrintIt: self size: 255+4.! !
"-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- "!
SCExampleStruct class
instanceVariableNames: ''!
!SCExampleStruct class methodsFor: 'fields' stamp: 'cds 12/10/2004 16:37'!
byteSize
^255+4! !
!SCExampleStruct class methodsFor: 'fields' stamp: 'cds 12/10/2004 16:37'!
fields
"self defineFields"
^#((someNumber 'long') (someString 'ExternalData' 255))! !
SCExampleStruct compileFields!
-------------- next part --------------
#include "ffiexample.h"
int printIt(MyStruct* s, int size) {
int i;
printf("%lx\n", s);
printf("%d\n", size);
printf("%d\n", s->someNumber);
printf("%lx\n", s->someString);
for(i=0; i < 255; i++) {
printf("%hhx:", s->someString[i]);
}
printf("\n");
}
-------------- next part --------------
typedef struct {
int someNumber;
char someString[255];
} MyStruct;
-------------- next part --------------
'From Squeak3.7 of ''4 September 2004'' [latest update: #5989] on 10 December 2004 at 4:51:12 pm'!
!String methodsFor: '*PalmPilot' stamp: 'cds 12/10/2004 16:24'!
asExternalCString: length
| add |
add := ExternalAddress allocate: length.
self halt.
1 to: self size do: [:i |
add byteAt: i put: (self at: i) asciiValue].
add byteAt: self size + 1 put: 0.
^ExternalData fromHandle: add type: ExternalType char! !
More information about the Squeak-dev
mailing list
|