--- a/ExternalFunctionCallback.st Sun Aug 16 18:14:23 2009 +0100
+++ b/ExternalFunctionCallback.st Wed Aug 19 17:14:36 2009 +0100
@@ -260,13 +260,13 @@
and handed out to C. (you can also hand out the callBack directly - as it is a subclass of
ExternalBytes.
The actual action of the callback can be changed (at any time later) with:
- cb action:[:args | Transcript showCR:args. true].
+ cb action:[:args | Transcript showCR:args. true].
- Eventually, the callback should be released:
- cb release.
+ Eventually, the callback MUST be released:
+ cb release.
[author:]
- Claus Gittinger
+ Claus Gittinger
"
!
@@ -291,6 +291,57 @@
"
! !
+!ExternalFunctionCallback class methodsFor:'common callbacks'!
+
+callbackFor:aBlock returnType:returnType argumentTypes:argumentTypes
+ "generate a callback for the ErrorCallbackProc signature:
+ ErrorCallbackProc(HWND hWnd, int nErrID, LPTSTR lpErrorText)
+ which, can be given to an external API call and which invokes the
+ three arg block when clled.
+ Do not forget to eventually release the callback to avoid a memory leak."
+
+ |cb|
+
+ self assert:(aBlock numArgs == argumentTypes size).
+
+ cb := ExternalFunctionCallback new.
+ cb returnType:returnType argumentTypes:argumentTypes.
+ cb beCallTypeWINAPI.
+ cb generateClosure.
+ cb action:aBlock.
+ "/ ^ cb code. 'can be passed to C'.
+ ^ cb
+
+ "
+ |cb|
+
+ cb := self errorCallbackProcFor:[:a1 :a2 :a3 | Transcript showCR:('%1 %2 %3' bindWith:a1 with:a2 with:a3)].
+ ExternalFunctionCallback testCall:cb withArguments:#(#[1 2 3] 456 'hello').
+ cb release
+ "
+!
+
+errorCallbackProcFor:aThreeArgBlock
+ "generate a callback for the ErrorCallbackProc signature:
+ ErrorCallbackProc(HWND hWnd, int nErrID, LPTSTR lpErrorText)
+ which, can be given to an external API call and which invokes the
+ three arg block when clled.
+ Do not forget to eventually release the callback to avoid a memory leak."
+
+ ^ self
+ callbackFor:aThreeArgBlock
+ returnType:#long
+ argumentTypes:#(handle int charPointer)
+
+ "
+ |cb|
+
+ cb := self errorCallbackProcFor:[:a1 :a2 :a3 | Transcript showCR:('%1 %2 %3' bindWith:a1 with:a2 with:a3)].
+ ExternalFunctionCallback testCall:cb withArguments:#(#[1 2 3] 456 'hello').
+ cb release
+ "
+! !
+
!ExternalFunctionCallback class methodsFor:'constants'!
callTypeAPI
@@ -326,26 +377,48 @@
testCall:aCallback withArgument:arg
"a simple test, if I can be called"
+
+ self testCall:aCallback withArguments:(Array with:arg)
+!
+
+testCall:aCallback withArguments:args
+ "a simple test, if I can be called"
%{
+# define MAX_ARGS 5
INTFUNC f = __externalAddressVal(aCallback);
INT result;
- void *c_arg = 0;
+ int i;
+ void *c_args[MAX_ARGS];
+
+ if (! __isArray(args))
+ goto badArg;
+ if (__arraySize(args) > MAX_ARGS)
+ goto badArg;
+
+ for (i=0; i < __arraySize(args); i++) {
+ OBJ arg = __ArrayInstPtr(args)->a_element[i];
- if (__isSmallInteger(arg)) {
- c_arg = (void *)(__intVal(arg));
- } else {
- if (arg == true) {
- c_arg = (void *)1;
- } else {
- if (__isString(arg)) {
- c_arg = (void *)__stringVal(arg);
- }
- }
+ if (__isSmallInteger(arg)) {
+ c_args[i] = (void *)(__intVal(arg));
+ } else if (arg == true) {
+ c_args[i] = (void *)1;
+ } else if (arg == false) {
+ c_args[i] = (void *)0;
+ } else if (__isString(arg)) {
+ c_args[i] = (void *)__stringVal(arg);
+ } else if (__isByteArray(arg)) {
+ c_args[i] = (void *)__byteArrayVal(arg);
+ } else
+ goto badArg;
}
- fprintf(stderr, "ExternalFunctionCallback: calling callBack %x(%x)\n", f, c_arg);
- result = (*f)(c_arg);
+ fprintf(stderr, "ExternalFunctionCallback: calling callBack %x(%x, %x)\n", f, c_args[0], c_args[1]);
+ result = (*f)(c_args[0], c_args[1], c_args[2], c_args[3], c_args[4]);
fprintf(stderr, "ExternalFunctionCallback: result from callBack is %x\n", result);
-%}
+ RETURN(true);
+
+badArg: ;
+%}.
+ self error:'bad argument'
! !
!ExternalFunctionCallback methodsFor:'accessing'!
@@ -746,15 +819,15 @@
__INST(code_) = 0;
if (pcl) {
- free(pcl);
+ free(pcl);
+ RETURN(self);
}
%}.
self invalidateReference.
-
! !
!ExternalFunctionCallback class methodsFor:'documentation'!
version
- ^ '$Id: ExternalFunctionCallback.st 10447 2009-06-14 13:09:55Z vranyj1 $'
+ ^ '$Id: ExternalFunctionCallback.st 10467 2009-08-19 16:14:36Z vranyj1 $'
! !