--- a/ExternalLibraryFunction.st Tue May 02 18:52:05 2006 +0200
+++ b/ExternalLibraryFunction.st Tue May 02 19:34:14 2006 +0200
@@ -186,7 +186,7 @@
returnTypeSymbol := self ffiTypeSymbolForType:returnType.
%{ /* UNLIMITEDSTACK */
-#ifdef HAVE_FFI
+#ifdef HAVE_FFI
ffi_cif __cif;
ffi_type *__argTypes[MAX_ARGS];
ffi_type *__returnType = NULL;
@@ -194,6 +194,7 @@
int iVal;
float fVal;
double dVal;
+ void *pointerVal;
};
union u __argValues[MAX_ARGS];
union u __returnValue;
@@ -226,6 +227,9 @@
goto error;
}
+ /*
+ * validate the return type
+ */
__returnValuePointer = &__returnValue;
if (returnTypeSymbol == @symbol(int)) {
__returnType = __get_ffi_type_sint();
@@ -266,11 +270,16 @@
} else if (returnTypeSymbol == @symbol(void)) {
__returnType = __get_ffi_type_void();
__returnValuePointer = NULL;
+ } else if (returnTypeSymbol == @symbol(pointer)) {
+ __returnType = __get_ffi_type_pointer();
} else {
failureCode = @symbol(UnknownReturnType);
goto error;
}
+ /*
+ * validate all arg types and setup arg-buffers
+ */
for (i=0; i<__numArgs; i++) {
ffi_type *thisType;
void *argValuePtr;
@@ -405,6 +414,25 @@
} else if (typeSymbol == @symbol(void)) {
thisType = __get_ffi_type_void();
argValuePtr = &null;
+ } else if (typeSymbol == @symbol(pointer)) {
+ thisType = __get_ffi_type_pointer();
+ if (__isExternalAddressLike(arg)) {
+ __argValues[i].pointerVal = (void *)(__externalAddressVal(arg));
+ } else if (__isExternalBytesLike(arg)) {
+ __argValues[i].pointerVal = (void *)(__externalBytesVal(arg));
+ } else if (__isByteArray(arg)) {
+ __argValues[i].pointerVal = (void *)(__byteArrayVal(arg));
+ } else if (__isFloatArray(arg)) {
+ __argValues[i].pointerVal = (void *)(__FloatArrayInstPtr(arg)->f_element);
+ } else if (__isDoubleArray(arg)) {
+ __argValues[i].pointerVal = (void *)(__DoubleArrayInstPtr(arg)->d_element);
+ } else if (__isString(arg) || __isSymbol(arg)) {
+ __argValues[i].pointerVal = (void *)(__stringVal(arg));
+ } else {
+ failureCode = @symbol(InvalidArgument);
+ goto error;
+ }
+ argValuePtr = &(__argValues[i].pointerVal);;
} else if (typeSymbol == @symbol(boolean)) {
thisType = __get_ffi_type_uint();
@@ -487,7 +515,11 @@
if (returnTypeSymbol == @symbol(void)) {
RETURN ( nil );
}
- failureCode = @symbol(UnknownReturnType);
+ if (returnTypeSymbol == @symbol(pointer)) {
+printf("returnvalue: %x\n", __returnValue.pointerVal);
+ RETURN ( __MKEXTERNALADDRESS(__returnValue.pointerVal) );
+ }
+ failureCode = @symbol(UnknownReturnType2);
error: ;
#else /* no FFI support */
@@ -506,17 +538,21 @@
|handle|
moduleName isNil ifTrue:[
- self error:'Missing moduleName'.
+ self error:'Missing moduleName'.
].
moduleHandle isNil ifTrue:[
- handle := ObjectFileLoader loadDynamicObject:moduleName.
- handle isNil ifTrue:[
- self error:'Cannot load module: ', moduleName.
- ].
- moduleHandle := handle.
+ handle := ObjectFileLoader loadDynamicObject:moduleName.
+ handle isNil ifTrue:[
+ handle := ObjectFileLoader
+ loadDynamicObject:(Filename currentDirectory construct:moduleName) pathName.
+ handle isNil ifTrue:[
+ self error:'Cannot load module: ', moduleName.
+ ].
+ ].
+ moduleHandle := handle.
].
(moduleHandle getFunctionAddress:name into:self) isNil ifTrue:[
- self error:'Missing function: ', name, ' in module: ', moduleName.
+ self error:'Missing function: ', name, ' in module: ', moduleName.
].
!
@@ -531,14 +567,26 @@
!ExternalLibraryFunction methodsFor:'private-accessing'!
ffiTypeSymbolForType:aType
+ |t|
"/ kludge for those who do not have the CType package...
- aType isSymbol ifTrue:[ ^ aType ].
+ t := aType.
+ t isSymbol ifFalse:[
+ aType isString ifFalse:[
+ CType isNil ifTrue:[
+ self error:'unknown type'.
+ ].
+ t := aType typeSymbol.
+ ].
+ aType isString ifTrue:[
+ self halt
+ ].
+ t isSymbol ifFalse:[
+ self error:'unknown type'.
+ ].
+ ].
- CType isNil ifTrue:[
- self error:'unknown type'.
- ].
- ^ aType typeSymbol
+ ^ t
!
name:functionName module:aModuleName callType:aCallType returnType:aReturnType argumentTypes:argTypes
@@ -552,5 +600,5 @@
!ExternalLibraryFunction class methodsFor:'documentation'!
version
- ^ '$Header: /cvs/stx/stx/libbasic/ExternalLibraryFunction.st,v 1.15 2006-05-02 16:52:05 cg Exp $'
+ ^ '$Header: /cvs/stx/stx/libbasic/ExternalLibraryFunction.st,v 1.16 2006-05-02 17:34:14 cg Exp $'
! !