Marcel Taeumel uploaded a new version of FFI-Callbacks to project FFI:
http://source.squeak.org/FFI/FFI-Callbacks-mt.9.mcz ==================== Summary ==================== Name: FFI-Callbacks-mt.9 Author: mt Time: 1 May 2021, 10:24:12.802394 am UUID: 937a46d5-7f6d-9344-8165-515cc5a54b55 Ancestors: FFI-Callbacks-mt.7 Restructure callback examples. Adds a fourth example that sorts integers. Complements FFI-Kernel-mt.123. =============== Diff against FFI-Callbacks-mt.7 =============== Item was removed: - ----- Method: FFICallback class>>exampleCqsort (in category 'examples') ----- - exampleCqsort - "Call the libc qsort function (which requires a callback)." - "FFICallback exampleCqsort" - "(Time millisecondsToRun: [100 timesRepeat: [FFICallback exampleCqsort]]) / 100.0" - - | type cb rand nElements sizeofDouble values orig sort libcName knownLibcNames fn | - - knownLibcNames := #('libobjc.dylib' 'libgcc_s.1.dylib' 'libc.dylib' 'libc.so.6' 'libc.so' 'msvcrt.dll'). - libcName := Project uiManager chooseFrom: knownLibcNames title: 'Choose your libc'. - libcName = 0 ifTrue: [^ self]. - libcName := knownLibcNames at: libcName. - - rand := Random new. - type := ExternalType double. - sizeofDouble := type byteSize. - nElements := 10. - values := ExternalData - fromHandle: (ExternalAddress allocate: nElements * sizeofDouble) - type: type asPointerType. - "Initialize external data and set size for enumeration." - 1 to: nElements do: [:i| values at: i put: rand next]. - values size: nElements. - "Fetch a local copy of the external data." - orig := values collect: [:each | each]. - - "Construct the callback structure." - cb := FFICallback - signature: '<callback: int (*)(double* double*)>' - "signature: #(int 'double*' 'double*')" - block: [ :arg1 :arg2 | - | a b | - a := arg1 doubleAt: 1. - b := arg2 doubleAt: 1. - Transcript showln: ('Comparing {1} and {2}' format: {a. b}). - self halt. - (a - b) sign]. - - "void qsort( void *base, size_t number, size_t width, int (__cdecl *compare )(const void *, const void *) );" - fn := ExternalLibraryFunction - name: 'qsort' module: libcName - callType: ExternalLibraryFunction callTypeCDecl - returnType: ExternalType void - argumentTypes: (ExternalType lookupTypes: #('void*' size_t size_t 'void*')). - - "Invoke!!" - fn invokeWith: values "getHandle" with: nElements with: sizeofDouble with: cb thunk "getHandle". - - sort := values collect: [:each | each]. - values getHandle free. - ^orig -> sort! Item was added: + ----- Method: FFICallback class>>exampleCqsort01 (in category 'examples') ----- + exampleCqsort01 + "Call the libc qsort function (which requires a callback)." + "FFICallback exampleCqsort01" + "(Time millisecondsToRun: [100 timesRepeat: [FFICallback exampleCqsort]]) / 100.0" + + | type cb rand nElements sizeofDouble values orig sort libcName knownLibcNames fn | + + knownLibcNames := #('libobjc.dylib' 'libgcc_s.1.dylib' 'libc.dylib' 'libc.so.6' 'libc.so' 'msvcrt.dll'). + libcName := Project uiManager chooseFrom: knownLibcNames title: 'Choose your libc'. + libcName = 0 ifTrue: [^ self]. + libcName := knownLibcNames at: libcName. + + rand := Random new. + type := ExternalType double. + sizeofDouble := type byteSize. + nElements := 10. + values := ExternalData + fromHandle: (ExternalAddress allocate: nElements * sizeofDouble) + type: type asPointerType. + "Initialize external data and set size for enumeration." + 1 to: nElements do: [:i| values at: i put: rand next]. + values size: nElements. + "Fetch a local copy of the external data." + orig := values collect: [:each | each]. + + "Construct the callback structure." + cb := FFICallback + signature: '<callback: int (*)(double* double*)>' + "signature: #(int 'double*' 'double*')" + block: [ :arg1 :arg2 | + | a b | + a := arg1 doubleAt: 1. + b := arg2 doubleAt: 1. + Transcript showln: ('Comparing {1} and {2}' format: {a. b}). + self halt. + (a - b) sign]. + + "void qsort( void *base, size_t number, size_t width, int (__cdecl *compare )(const void *, const void *) );" + fn := ExternalLibraryFunction + name: 'qsort' module: libcName + callType: ExternalLibraryFunction callTypeCDecl + returnType: ExternalType void + argumentTypes: (ExternalType lookupTypes: #('void*' size_t size_t 'void*')). + + "Invoke!!" + fn invokeWith: values "getHandle" with: nElements with: sizeofDouble with: cb thunk "getHandle". + + sort := values collect: [:each | each]. + values getHandle free. + ^orig -> sort! Item was added: + ----- Method: FFICallback class>>exampleCqsort02 (in category 'examples') ----- + exampleCqsort02 + "Call the libc qsort function (which requires a callback)." + " + FFICallback exampleCqsort02 + " + "(Time millisecondsToRun: [100 timesRepeat: [FFICallback exampleCqsort]]) / 100.0" + + | type rand nElements sizeofDouble values orig sort | + + rand := Random new. + type := ExternalType double. + sizeofDouble := type byteSize. + nElements := 10. + values := ExternalData + fromHandle: (ExternalAddress allocate: nElements * sizeofDouble) + type: type asPointerType. + "Initialize external data and set size for enumeration." + 1 to: nElements do: [:i| values at: i put: rand next]. + values size: nElements. + "Fetch a local copy of the external data." + orig := values collect: [:each | each]. + + "Invoke!!" + self + qsort: values with: nElements with: sizeofDouble + with: [ :arg1 :arg2 | + | a b | + a := arg1 doubleAt: 1. + b := arg2 doubleAt: 1. + Transcript showln: ('Comparing {1} and {2}' format: {a. b}). + self halt. + (a - b) sign]. + + sort := values collect: [:each | each]. + values getHandle free. + ^orig -> sort! Item was added: + ----- Method: FFICallback class>>exampleCqsort03 (in category 'examples') ----- + exampleCqsort03 + "Call the libc qsort function (which requires a callback)." + " + FFICallback exampleCqsort03 + " + "(Time millisecondsToRun: [100 timesRepeat: [FFICallback exampleCqsort]]) / 100.0" + + | type rand nElements sizeofDouble values orig sort cb | + + rand := Random new. + type := ExternalType double. + sizeofDouble := type byteSize. + nElements := 10. + values := ExternalData + fromHandle: (ExternalAddress allocate: nElements * sizeofDouble) + type: type asPointerType. + "Initialize external data and set size for enumeration." + 1 to: nElements do: [:i| values at: i put: rand next]. + values size: nElements. + "Fetch a local copy of the external data." + orig := values collect: [:each | each]. + + "Construct the callback structure." + cb := FFICallback + signature: '<callback: int (*)(double* double*)>' + "signature: #(int 'double*' 'double*')" + block: [ :arg1 :arg2 | + | a b | + a := arg1 doubleAt: 1. + b := arg2 doubleAt: 1. + Transcript showln: ('Comparing {1} and {2}' format: {a. b}). + self halt. + (a - b) sign]. + + + "Invoke!!" + self + cdeclQsort: values with: nElements with: sizeofDouble + with: cb thunk. + + sort := values collect: [:each | each]. + values getHandle free. + ^orig -> sort! Item was added: + ----- Method: FFICallback class>>exampleCqsort04 (in category 'examples') ----- + exampleCqsort04 + " + FFICallback exampleCqsort04 + " + + | type in out fn cb | + type := ExternalType int32_t. + in := type allocateExternal: 10. + 1 to: in size do: [:each | + in at: each put: 100 atRandom]. + + cb := FFICallback + signature: '<callback: int (*)(int32_t* int32_t*)>' + "signature: #(int 'double*' 'double*')" + block: [ :arg1 :arg2 | + | a b | + a := arg1 signedLongAt: 1. + b := arg2 signedLongAt: 1. + Transcript showln: ('Comparing {1} and {2}' format: {a. b}). + "self halt." + (a - b) sign]. + + fn := ExternalLibraryFunction + name: 'qsort' module: 'msvcrt.dll' + callType: ExternalLibraryFunction callTypeCDecl + returnType: ExternalType void + argumentTypes: (ExternalType lookupTypes: #('void*' size_t size_t 'void*')). + + "Invoke!!" + fn + invokeWith: in "getHandle" + with: in size + with: in contentType byteSize + with: cb thunk "getHandle". + + out := in collect: [:each | each]. + in free. + ^ out! Item was removed: - ----- Method: FFICallback class>>exampleCqsortThree (in category 'examples') ----- - exampleCqsortThree - "Call the libc qsort function (which requires a callback)." - " - FFICallback exampleCqsortThree - " - "(Time millisecondsToRun: [100 timesRepeat: [FFICallback exampleCqsort]]) / 100.0" - - | type rand nElements sizeofDouble values orig sort cb | - - rand := Random new. - type := ExternalType double. - sizeofDouble := type byteSize. - nElements := 10. - values := ExternalData - fromHandle: (ExternalAddress allocate: nElements * sizeofDouble) - type: type asPointerType. - "Initialize external data and set size for enumeration." - 1 to: nElements do: [:i| values at: i put: rand next]. - values size: nElements. - "Fetch a local copy of the external data." - orig := values collect: [:each | each]. - - "Construct the callback structure." - cb := FFICallback - signature: '<callback: int (*)(double* double*)>' - "signature: #(int 'double*' 'double*')" - block: [ :arg1 :arg2 | - | a b | - a := arg1 doubleAt: 1. - b := arg2 doubleAt: 1. - Transcript showln: ('Comparing {1} and {2}' format: {a. b}). - self halt. - (a - b) sign]. - - - "Invoke!!" - self - cdeclQsort: values with: nElements with: sizeofDouble - with: cb thunk. - - sort := values collect: [:each | each]. - values getHandle free. - ^orig -> sort! Item was removed: - ----- Method: FFICallback class>>exampleCqsortTwo (in category 'examples') ----- - exampleCqsortTwo - "Call the libc qsort function (which requires a callback)." - " - FFICallback exampleCqsortTwo - " - "(Time millisecondsToRun: [100 timesRepeat: [FFICallback exampleCqsort]]) / 100.0" - - | type rand nElements sizeofDouble values orig sort | - - rand := Random new. - type := ExternalType double. - sizeofDouble := type byteSize. - nElements := 10. - values := ExternalData - fromHandle: (ExternalAddress allocate: nElements * sizeofDouble) - type: type asPointerType. - "Initialize external data and set size for enumeration." - 1 to: nElements do: [:i| values at: i put: rand next]. - values size: nElements. - "Fetch a local copy of the external data." - orig := values collect: [:each | each]. - - "Invoke!!" - self - qsort: values with: nElements with: sizeofDouble - with: [ :arg1 :arg2 | - | a b | - a := arg1 doubleAt: 1. - b := arg2 doubleAt: 1. - Transcript showln: ('Comparing {1} and {2}' format: {a. b}). - self halt. - (a - b) sign]. - - sort := values collect: [:each | each]. - values getHandle free. - ^orig -> sort! |
Free forum by Nabble | Edit this page |