*** empty log message ***
authorClaus Gittinger <cg@exept.de>
Tue, 02 May 2006 19:34:14 +0200
changeset 9340 df61c7e20801
parent 9339 a833dc3f5702
child 9341 719fcf48695b
*** empty log message ***
ExternalLibraryFunction.st
--- 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 $'
 ! !