ExternalLibraryFunction.st
changeset 9322 41c391bfbf03
parent 9321 734c7c432461
child 9324 96279896d95f
equal deleted inserted replaced
9321:734c7c432461 9322:41c391bfbf03
     1 "
     1 "
     2  COPYRIGHT (c) 2004 by eXept Software AG
     2  COPYRIGHT (c) 2004 by eXept Software AG
     3               All Rights Reserved
     3 	      All Rights Reserved
     4 
     4 
     5  This software is furnished under a license and may be used
     5  This software is furnished under a license and may be used
     6  only in accordance with the terms of that license and with the
     6  only in accordance with the terms of that license and with the
     7  inclusion of the above copyright notice.   This software may not
     7  inclusion of the above copyright notice.   This software may not
     8  be provided or otherwise made available to, or used by, any
     8  be provided or otherwise made available to, or used by, any
    17 	classVariableNames:''
    17 	classVariableNames:''
    18 	poolDictionaries:''
    18 	poolDictionaries:''
    19 	category:'System-Support'
    19 	category:'System-Support'
    20 !
    20 !
    21 
    21 
       
    22 !ExternalLibraryFunction primitiveDefinitions!
       
    23 %{
       
    24 # include <ffi.h>
       
    25 
       
    26 # define MAX_ARGS    128
       
    27 
       
    28 # define STX_FFI_TYPE_VOID              0
       
    29 # define STX_FFI_TYPE_INT               1
       
    30 # define STX_FFI_TYPE_FLOAT             2
       
    31 # define STX_FFI_TYPE_DOUBLE            3
       
    32 # define STX_FFI_TYPE_LONGDOUBLE        4
       
    33 # define STX_FFI_TYPE_UINT8             5
       
    34 # define STX_FFI_TYPE_SINT8             6
       
    35 # define STX_FFI_TYPE_UINT16            7
       
    36 # define STX_FFI_TYPE_SINT16            8
       
    37 # define STX_FFI_TYPE_UINT32            9
       
    38 # define STX_FFI_TYPE_SINT32            10
       
    39 # define STX_FFI_TYPE_UINT64            11
       
    40 # define STX_FFI_TYPE_SINT64            12
       
    41 # define STX_FFI_TYPE_STRUCT            0x10000        /* + size */
       
    42 # define STX_FFI_TYPE_STRUCT_SIZE_MASK  0x0FFFF        /* size mask */
       
    43 # define STX_FFI_TYPE_POINTER           13
       
    44 
       
    45 %}
       
    46 ! !
       
    47 
    22 !ExternalLibraryFunction class methodsFor:'documentation'!
    48 !ExternalLibraryFunction class methodsFor:'documentation'!
    23 
    49 
    24 copyright
    50 copyright
    25 "
    51 "
    26  COPYRIGHT (c) 2004 by eXept Software AG
    52  COPYRIGHT (c) 2004 by eXept Software AG
    27               All Rights Reserved
    53 	      All Rights Reserved
    28 
    54 
    29  This software is furnished under a license and may be used
    55  This software is furnished under a license and may be used
    30  only in accordance with the terms of that license and with the
    56  only in accordance with the terms of that license and with the
    31  inclusion of the above copyright notice.   This software may not
    57  inclusion of the above copyright notice.   This software may not
    32  be provided or otherwise made available to, or used by, any
    58  be provided or otherwise made available to, or used by, any
    33  other person.  No title to or ownership of the software is
    59  other person.  No title to or ownership of the software is
    34  hereby transferred.
    60  hereby transferred.
    35 "
    61 "
       
    62 !
       
    63 
       
    64 example
       
    65 "
       
    66         |f|
       
    67 
       
    68         f := ExternalLibraryFunction new.
       
    69         f name:'MessageBeep'
       
    70           module:'user32.dll'
       
    71           callType:#WINAPI
       
    72           returnType:#boolean
       
    73           argumentTypes:#(uint).
       
    74 
       
    75         f invokeWith:1.
       
    76 "
    36 ! !
    77 ! !
    37 
    78 
    38 !ExternalLibraryFunction class methodsFor:'instance creation'!
    79 !ExternalLibraryFunction class methodsFor:'instance creation'!
    39 
    80 
    40 name:functionName module:moduleName callType:callType 
    81 name:functionName module:moduleName callType:callType
    41                   returnType:returnType argumentTypes:argTypes
    82 		  returnType:returnType argumentTypes:argTypes
    42     ^ self new
    83     ^ self new
    43         name:functionName module:moduleName callType:callType 
    84 	name:functionName module:moduleName callType:callType
    44         returnType:returnType argumentTypes:argTypes
    85 	returnType:returnType argumentTypes:argTypes
    45 ! !
    86 ! !
    46 
    87 
    47 !ExternalLibraryFunction class methodsFor:'constants'!
    88 !ExternalLibraryFunction class methodsFor:'constants'!
    48 
    89 
    49 callTypeAPI
    90 callTypeAPI
    70 
   111 
    71 !ExternalLibraryFunction methodsFor:'invoking'!
   112 !ExternalLibraryFunction methodsFor:'invoking'!
    72 
   113 
    73 invoke
   114 invoke
    74     self hasCode ifFalse:[
   115     self hasCode ifFalse:[
    75         self prepareInvoke.
   116 	self prepareInvoke.
    76     ].
   117     ].
    77     ^ self invokeFFIWithArguments:#()
   118     ^ self invokeFFIWithArguments:#()
    78 !
   119 !
    79 
   120 
    80 invokeWith:arg
   121 invokeWith:arg
    81     self hasCode ifFalse:[
   122     self hasCode ifFalse:[
    82         self prepareInvoke.
   123 	self prepareInvoke.
    83     ].
   124     ].
    84     ^ self invokeFFIWithArguments:(Array with:arg)
   125     ^ self invokeFFIWithArguments:(Array with:arg)
    85 !
   126 !
    86 
   127 
    87 invokeWith:arg1 with:arg2
   128 invokeWith:arg1 with:arg2
    88     self hasCode ifFalse:[
   129     self hasCode ifFalse:[
    89         self prepareInvoke.
   130 	self prepareInvoke.
    90     ].
   131     ].
    91     ^ self invokeFFIWithArguments:(Array with:arg1 with:arg2)
   132     ^ self invokeFFIWithArguments:(Array with:arg1 with:arg2)
    92 !
   133 !
    93 
   134 
    94 invokeWith:arg1 with:arg2 with:arg3
   135 invokeWith:arg1 with:arg2 with:arg3
    95     self hasCode ifFalse:[
   136     self hasCode ifFalse:[
    96         self prepareInvoke.
   137 	self prepareInvoke.
    97     ].
   138     ].
    98     ^ self invokeFFIWithArguments:(Array with:arg1 with:arg2 with:arg3)
   139     ^ self invokeFFIWithArguments:(Array with:arg1 with:arg2 with:arg3)
    99 !
   140 !
   100 
   141 
   101 invokeWith:arg1 with:arg2 with:arg3 with:arg4
   142 invokeWith:arg1 with:arg2 with:arg3 with:arg4
   102     self hasCode ifFalse:[
   143     self hasCode ifFalse:[
   103         self prepareInvoke.
   144 	self prepareInvoke.
   104     ].
   145     ].
   105     ^ self invokeFFIWithArguments:(Array with:arg1 with:arg2 with:arg3 with:arg4)
   146     ^ self invokeFFIWithArguments:(Array with:arg1 with:arg2 with:arg3 with:arg4)
   106 !
   147 !
   107 
   148 
   108 invokeWithArguments:argArray
   149 invokeWithArguments:argArray
   109     self hasCode ifFalse:[
   150     self hasCode ifFalse:[
   110         self prepareInvoke.
   151 	self prepareInvoke.
   111     ].
   152     ].
   112     ^ self invokeFFIWithArguments:argArray
   153     ^ self invokeFFIWithArguments:argArray
   113 ! !
   154 ! !
   114 
   155 
   115 !ExternalLibraryFunction methodsFor:'printing'!
   156 !ExternalLibraryFunction methodsFor:'printing'!
   125 ! !
   166 ! !
   126 
   167 
   127 !ExternalLibraryFunction methodsFor:'private'!
   168 !ExternalLibraryFunction methodsFor:'private'!
   128 
   169 
   129 invokeFFIWithArguments:arguments
   170 invokeFFIWithArguments:arguments
   130     |ffiArgTypes failureCode|
   171     |argTypeSymbols returnTypeSymbol failureCode|
   131 
   172 
   132     argumentTypes notNil ifTrue:[
   173     argumentTypes notNil ifTrue:[
   133         ffiArgTypes := argumentTypes collect:[:argType | self ffiArgTypeForType:argType].
   174         argTypeSymbols := argumentTypes collect:[:argType | self ffiTypeSymbolForType:argType].
   134     ].
   175     ].
   135 %{
   176     returnTypeSymbol := self ffiTypeSymbolForType:returnType.
   136 #if defined(i386)
   177 
   137 # ifndef STX_FFI_TYPE_VOID
   178 %{
   138 #  define STX_FFI_TYPE_VOID         0
   179     ffi_type *argTypes[MAX_ARGS];
   139 #  define STX_FFI_TYPE_INT          1
   180     union {
   140 #  define STX_FFI_TYPE_FLOAT        2
   181         int iVal;
   141 #  define STX_FFI_TYPE_DOUBLE       3
   182     } argValues[MAX_ARGS];
   142 #  define STX_FFI_TYPE_LONGDOUBLE   4
   183     void *argValuePointers[MAX_ARGS];
   143 #  define STX_FFI_TYPE_UINT8        5
       
   144 #  define STX_FFI_TYPE_SINT8        6
       
   145 #  define STX_FFI_TYPE_UINT16       7
       
   146 #  define STX_FFI_TYPE_SINT16       8
       
   147 #  define STX_FFI_TYPE_UINT32       9
       
   148 #  define STX_FFI_TYPE_SINT32       10
       
   149 #  define STX_FFI_TYPE_UINT64       11
       
   150 #  define STX_FFI_TYPE_SINT64       12
       
   151 #  define STX_FFI_TYPE_STRUCT       13
       
   152 #  define STX_FFI_TYPE_POINTER      14
       
   153 
       
   154 # define MAX_NUMARGS    128
       
   155 typedef void * ffi_type;
       
   156 # endif
       
   157 
       
   158     void *argValues[MAX_NUMARGS];
       
   159     ffi_type *argtypes[MAX_NUMARGS];
       
   160     int numArgs;
   184     int numArgs;
   161     int i;
   185     int i;
       
   186     static int null = 0;
   162 
   187 
   163     if (arguments == nil) {
   188     if (arguments == nil) {
   164         numArgs = 0;
   189         numArgs = 0;
   165         if (ffiArgTypes != nil) {
   190         if (argTypeSymbols != nil) {
   166             if (! __isArray(ffiArgTypes)) goto error;
   191             if (! __isArray(argTypeSymbols)) goto error;
   167             if (__arraySize(ffiArgTypes) != numArgs) goto error;
   192             if (__arraySize(argTypeSymbols) != numArgs) goto error;
   168         }
   193         }
   169     } else {
   194     } else {
   170         if (! __isArray(arguments)) goto error;
   195         if (! __isArray(arguments)) goto error;
   171         numArgs = __arraySize(arguments);
   196         numArgs = __arraySize(arguments);
   172         if (! __isArray(ffiArgTypes)) goto error;
   197         if (! __isArray(argTypeSymbols)) goto error;
   173         if (__arraySize(ffiArgTypes) != numArgs) goto error;
   198         if (__arraySize(argTypeSymbols) != numArgs) goto error;
   174     }
   199     }
   175     if (numArgs > MAX_NUMARGS) {
   200     if (numArgs > MAX_ARGS) {
   176         failureCode = @symbol(TooManyArguments);
   201         failureCode = @symbol(TooManyArguments);
   177         goto error;
   202         goto error;
   178     }
   203     }
       
   204 
   179     for (i=0; i<numArgs; i++) {
   205     for (i=0; i<numArgs; i++) {
   180         switch (__intVal( __ArrayInstPtr(ffiArgTypes)->a_element[i]) ) {
   206         ffi_type *argType;
   181             case STX_FFI_TYPE_VOID:
   207         void *argValuePtr;
   182             case STX_FFI_TYPE_INT:
   208         OBJ typeSymbol;
   183             case STX_FFI_TYPE_FLOAT:
   209 
   184             case STX_FFI_TYPE_DOUBLE:
   210         typeSymbol = __ArrayInstPtr(argTypeSymbols)->a_element[i];
   185             case STX_FFI_TYPE_LONGDOUBLE:
   211         if (typeSymbol == @symbol(int)) {
   186             case STX_FFI_TYPE_UINT8:
   212         } else if (typeSymbol == @symbol(void)) {
   187             case STX_FFI_TYPE_SINT8:
   213 #if 0
   188             case STX_FFI_TYPE_UINT16:
   214             argType = &ffi_type_void;
   189             case STX_FFI_TYPE_SINT16:
   215 #endif
   190             case STX_FFI_TYPE_UINT32:
   216             argValuePtr = &null;
   191             case STX_FFI_TYPE_SINT32:
   217         } else {
   192             case STX_FFI_TYPE_UINT64:
   218             failureCode = @symbol(UnknownArgumentType);
   193             case STX_FFI_TYPE_SINT64:
   219             goto error;
   194             case STX_FFI_TYPE_STRUCT:
       
   195             case STX_FFI_TYPE_POINTER:
       
   196             default:
       
   197                 failureCode = @symbol(UnknownArgumentType);
       
   198                 goto error;
       
   199         }
   220         }
       
   221 
       
   222         argTypes[i] = argType;
       
   223         argValuePointers[i] = argValuePtr;
   200     }
   224     }
   201 
   225 
   202 #else
   226 # if 0
       
   227     /* Initialize the cif */
       
   228     CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1,
       
   229                        &ffi_type_sint64, args) == FFI_OK);
       
   230 
   203     argtypes = (ffi_type **)C_alloca(sizeof(ffi_type *) * (n + 3));
   231     argtypes = (ffi_type **)C_alloca(sizeof(ffi_type *) * (n + 3));
   204     argvalues = (void **)C_alloca(sizeof(void *) * (n + 3));
   232     argvalues = (void **)C_alloca(sizeof(void *) * (n + 3));
   205     argtypes[ 0 ] = &ffi_type_pointer;
   233     argtypes[ 0 ] = &ffi_type_pointer;
   206     argtypes[ 1 ] = &ffi_type_pointer;
   234     argtypes[ 1 ] = &ffi_type_pointer;
   207     argtypes[ 2 ] = &ffi_type_pointer;
   235     argtypes[ 2 ] = &ffi_type_pointer;
   217 
   245 
   218     C_temporary_stack = C_temporary_stack_bottom;
   246     C_temporary_stack = C_temporary_stack_bottom;
   219     status = ffi_prep_cif(&cif, FFI_DEFAULT_ABI, n + 3, &ffi_type_void, argtypes);
   247     status = ffi_prep_cif(&cif, FFI_DEFAULT_ABI, n + 3, &ffi_type_void, argtypes);
   220     assert(status == FFI_OK);
   248     assert(status == FFI_OK);
   221     ffi_call(&cif, (void *)C_block_item(fn, 0), NULL, argvalues);
   249     ffi_call(&cif, (void *)C_block_item(fn, 0), NULL, argvalues);
   222 #endif
   250 # endif
       
   251 
   223 error: ;
   252 error: ;
   224 %}
   253 %}
   225 !
   254 !
   226 
   255 
   227 linkToModule
   256 linkToModule
   229      I.e. retrieve the module handle and the code pointer."
   258      I.e. retrieve the module handle and the code pointer."
   230 
   259 
   231     |handle code|
   260     |handle code|
   232 
   261 
   233     moduleName isNil ifTrue:[
   262     moduleName isNil ifTrue:[
   234         self error:'Missing moduleName'.
   263 	self error:'Missing moduleName'.
   235     ].
   264     ].
   236 
   265 
   237     handle := ObjectFileLoader loadDynamicObject:moduleName.
   266     handle := ObjectFileLoader loadDynamicObject:moduleName.
   238     handle isNil ifTrue:[
   267     handle isNil ifTrue:[
   239         self error:'Cannot load module: ', moduleName.
   268 	self error:'Cannot load module: ', moduleName.
   240     ].
   269     ].
   241     moduleHandle := handle.
   270     moduleHandle := handle.
   242     code := moduleHandle getFunctionAddress:name into:self.
   271     code := moduleHandle getFunctionAddress:name into:self.
   243     code isNil ifTrue:[
   272     code isNil ifTrue:[
   244         self error:'Missing function: ', name, ' in module: ', moduleName.
   273 	self error:'Missing function: ', name, ' in module: ', moduleName.
   245     ].
   274     ].
   246 !
   275 !
   247 
   276 
   248 prepareInvoke
   277 prepareInvoke
   249     self hasCode ifFalse:[
   278     self hasCode ifFalse:[
   250         moduleHandle isNil ifTrue:[
   279 	moduleHandle isNil ifTrue:[
   251             self linkToModule.
   280 	    self linkToModule.
   252             self setupFFI.
   281 	    self setupFFI.
   253         ].
   282 	].
   254     ].
   283     ].
   255 !
   284 !
   256 
   285 
   257 setupFFI
   286 setupFFI
   258     "setup foreign function interface"
   287     "setup foreign function interface"
   259 
   288 
   260 "/    %{
   289 "/    %{
   261 "/    #if defined(WIN32) && defined(i386)
   290 "/    #if defined(WIN32) && defined(i386)
   262 "/        /* Have special code for this case - no need to use of ffi code. */
   291 "/        /* Have special code for this case - no need to use of ffi code. */
   263 "/    #else
   292 "/    #else
   264 "/        if (ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, &ffi_type_uint, args)) != FFI_OK)
   293 "/        if (ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, &ffi_type_uint, args)) 
   265 "/    #endif
       
   266 "/    %}
       
   267 ! !
   294 ! !
   268 
   295 
   269 !ExternalLibraryFunction methodsFor:'private-accessing'!
   296 !ExternalLibraryFunction methodsFor:'private-accessing'!
   270 
   297 
   271 name:functionName module:aModuleName callType:aCallType returnType:aReturnType argumentTypes:argTypes 
   298 STX_FFI_TYPE_DOUBLE
       
   299 %{
       
   300     RETURN(__MKSMALLINT(STX_FFI_TYPE_DOUBLE));
       
   301 %}.
       
   302 
       
   303     "
       
   304      self new STX_FFI_TYPE_DOUBLE
       
   305     "
       
   306 !
       
   307 
       
   308 STX_FFI_TYPE_FLOAT
       
   309 %{
       
   310     RETURN(__MKSMALLINT(STX_FFI_TYPE_FLOAT));
       
   311 %}.
       
   312 
       
   313     "
       
   314      self new STX_FFI_TYPE_FLOAT
       
   315     "
       
   316 !
       
   317 
       
   318 STX_FFI_TYPE_LONGDOUBLE
       
   319 %{
       
   320     RETURN(__MKSMALLINT(STX_FFI_TYPE_LONGDOUBLE));
       
   321 %}.
       
   322 
       
   323     "
       
   324      self new STX_FFI_TYPE_LONGDOUBLE
       
   325     "
       
   326 !
       
   327 
       
   328 STX_FFI_TYPE_POINTER
       
   329 %{
       
   330     RETURN(__MKSMALLINT(STX_FFI_TYPE_POINTER));
       
   331 %}.
       
   332 
       
   333     "
       
   334      self new STX_FFI_TYPE_POINTER
       
   335     "
       
   336 !
       
   337 
       
   338 STX_FFI_TYPE_SINT
       
   339 %{
       
   340 #if sizeof(int) == 4 
       
   341     RETURN(__MKSMALLINT(STX_FFI_TYPE_SINT32));
       
   342 #endif
       
   343 #if sizeof(int) == 8 
       
   344     RETURN(__MKSMALLINT(STX_FFI_TYPE_SINT64));
       
   345 #endif
       
   346 %}.
       
   347     self primitiveFailed
       
   348 
       
   349     "
       
   350      self new STX_FFI_TYPE_SINT
       
   351     "
       
   352 !
       
   353 
       
   354 STX_FFI_TYPE_SINT16
       
   355 %{
       
   356     RETURN(__MKSMALLINT(STX_FFI_TYPE_SINT16));
       
   357 %}.
       
   358 
       
   359     "
       
   360      self new STX_FFI_TYPE_SINT16
       
   361     "
       
   362 !
       
   363 
       
   364 STX_FFI_TYPE_SINT32
       
   365 %{
       
   366     RETURN(__MKSMALLINT(STX_FFI_TYPE_SINT32));
       
   367 %}.
       
   368 
       
   369     "
       
   370      self new STX_FFI_TYPE_SINT32
       
   371     "
       
   372 !
       
   373 
       
   374 STX_FFI_TYPE_SINT64
       
   375 %{
       
   376     RETURN(__MKSMALLINT(STX_FFI_TYPE_SINT64));
       
   377 %}.
       
   378 
       
   379     "
       
   380      self new STX_FFI_TYPE_SINT64
       
   381     "
       
   382 !
       
   383 
       
   384 STX_FFI_TYPE_SINT8
       
   385 %{
       
   386     RETURN(__MKSMALLINT(STX_FFI_TYPE_SINT8));
       
   387 %}.
       
   388 
       
   389     "
       
   390      self new STX_FFI_TYPE_SINT8
       
   391     "
       
   392 !
       
   393 
       
   394 STX_FFI_TYPE_STRUCT
       
   395 %{
       
   396     RETURN(__MKSMALLINT(STX_FFI_TYPE_STRUCT));
       
   397 %}.
       
   398 
       
   399     "
       
   400      self new STX_FFI_TYPE_STRUCT
       
   401     "
       
   402 !
       
   403 
       
   404 STX_FFI_TYPE_STRUCT:size
       
   405     ^ self STX_FFI_TYPE_STRUCT + size
       
   406 
       
   407     "
       
   408      self new STX_FFI_TYPE_STRUCT:0
       
   409      self new STX_FFI_TYPE_STRUCT:16 
       
   410     "
       
   411 !
       
   412 
       
   413 STX_FFI_TYPE_UINT
       
   414 %{
       
   415 #if sizeof(int) == 4 
       
   416     RETURN(__MKSMALLINT(STX_FFI_TYPE_UINT32));
       
   417 #endif
       
   418 #if sizeof(int) == 8 
       
   419     RETURN(__MKSMALLINT(STX_FFI_TYPE_UINT64));
       
   420 #endif
       
   421 %}.
       
   422     self primitiveFailed
       
   423 
       
   424     "
       
   425      self new STX_FFI_TYPE_UINT
       
   426     "
       
   427 !
       
   428 
       
   429 STX_FFI_TYPE_UINT16
       
   430 %{
       
   431     RETURN(__MKSMALLINT(STX_FFI_TYPE_UINT16));
       
   432 %}.
       
   433 
       
   434     "
       
   435      self new STX_FFI_TYPE_UINT16
       
   436     "
       
   437 !
       
   438 
       
   439 STX_FFI_TYPE_UINT64
       
   440 %{
       
   441     RETURN(__MKSMALLINT(STX_FFI_TYPE_UINT64));
       
   442 %}.
       
   443 
       
   444     "
       
   445      self new STX_FFI_TYPE_UINT64
       
   446     "
       
   447 !
       
   448 
       
   449 STX_FFI_TYPE_UINT8
       
   450 %{
       
   451     RETURN(__MKSMALLINT(STX_FFI_TYPE_UINT8));
       
   452 %}.
       
   453 
       
   454     "
       
   455      self new STX_FFI_TYPE_UINT8
       
   456     "
       
   457 !
       
   458 
       
   459 STX_FFI_TYPE_VOID
       
   460 %{
       
   461     RETURN(__MKSMALLINT(STX_FFI_TYPE_VOID));
       
   462 %}
       
   463 
       
   464     "
       
   465      self new STX_FFI_TYPE_VOID
       
   466     "
       
   467 !
       
   468 
       
   469 ffiTypeForType:aType
       
   470     "/ kludge
       
   471 
       
   472     aType isSymbol ifTrue:[
       
   473         "/ for those who do not have the CType package...
       
   474         aType == #int ifTrue:[ ^ self STX_FFI_TYPE_INT ].
       
   475         aType == #uint ifTrue:[ ^ self STX_FFI_TYPE_UINT ].
       
   476         aType == #short ifTrue:[ ^ self STX_FFI_TYPE_SHORT ].
       
   477         aType == #ushort ifTrue:[ ^ self STX_FFI_TYPE_USHORT ].
       
   478         aType == #long ifTrue:[ ^ self STX_FFI_TYPE_LONG ].
       
   479         aType == #ulong ifTrue:[ ^ self STX_FFI_TYPE_ULONG ].
       
   480         aType == #float ifTrue:[ ^ self STX_FFI_TYPE_FLOAT ].
       
   481         aType == #double ifTrue:[ ^ self STX_FFI_TYPE_DOUBLE ].
       
   482         aType == #void ifTrue:[ ^ self STX_FFI_TYPE_VOID ].
       
   483         self error:'unknown type'.
       
   484     ].
       
   485     self error:'unknown type'.
       
   486 !
       
   487 
       
   488 ffiTypeSymbolForType:aType
       
   489     "/ kludge for those who do not have the CType package...
       
   490     aType isSymbol ifTrue:[ ^ aType ].
       
   491     CType isNil ifTrue:[
       
   492         self error:'unknown type'.
       
   493     ].
       
   494     ^ aType typeSymbol
       
   495 !
       
   496 
       
   497 name:functionName module:aModuleName callType:aCallType returnType:aReturnType argumentTypes:argTypes
   272     name := functionName.
   498     name := functionName.
   273     moduleName := aModuleName.
   499     moduleName := aModuleName.
   274     callType := aCallType.
   500     callType := aCallType.
   275     returnType := aReturnType.
   501     returnType := aReturnType.
   276     argumentTypes := argTypes.
   502     argumentTypes := argTypes.
   277 ! !
   503 ! !
   278 
   504 
   279 !ExternalLibraryFunction class methodsFor:'documentation'!
   505 !ExternalLibraryFunction class methodsFor:'documentation'!
   280 
   506 
   281 version
   507 version
   282     ^ '$Header: /cvs/stx/stx/libbasic/ExternalLibraryFunction.st,v 1.5 2006-04-24 08:49:16 cg Exp $'
   508     ^ '$Header: /cvs/stx/stx/libbasic/ExternalLibraryFunction.st,v 1.6 2006-04-25 10:33:27 cg Exp $'
   283 ! !
   509 ! !