FFI Variables

Andreas Raab Andreas.Raab at gmx.de
Sun Apr 21 23:51:41 UTC 2002


Hi,

> <apicall: long 'RecField' (byte long) module: 'xxxx.dll'>

First of all, I said "byte *" (POINTER to byte) or "void *" (POINTER to
void) instead of "char *" (POINTER to char).

> I`d  expect that the second call would return the string

It won't since what you are expecting simply doesn't exist. An argument
cannot be used to return a value. What you have to do is to pass in a
pointer which will receive the result. Here's how this goes:

* fix the function declaration:
	<apicall: long 'RecField' (byte* long) module: 'xxxx.dll'>

* allocate a variable to hold the pointer:
	stub := ByteArray new: 4.

* call the function:
	n := self RecField: stub with: 32000.

* get an externl address from the result:
	xAddr := stub asExternalPointer.

* internalize the allocated string if needed:
	a) if it's a C string:
		index := 0.
		string := String streamContents:[:s|
			[cc := xAddr unsignedCharAt: index.
			cc asciiValue = 0] whileFalse:[s nextPut: cc].
		].
	b) if n contains the length:
		string := String streamContents:[:s|
			0 to: n-1 do:[:i| s nextPut: (xAddr
unsignedCharAt: i)].
		].

* clean up the string if needed
	xAddr free.

Cheers,
  - Andreas




More information about the Squeak-dev mailing list