[Win32utils-devel] Patch for Callback [win32utils-Bugs-21275]

Heesob Park phasis at gmail.com
Sun Jul 20 22:49:25 EDT 2008


Hi,

Here is a patch for callback support:

--- api.c.org   2008-07-21 11:30:55.000000000 +0900
+++ api.c       2008-07-21 11:29:49.000000000 +0900
@@ -470,16 +470,18 @@
    DWORD params[1];
 } PARAM;

-static VALUE ActiveCallback;
+static VALUE CallbackTable = Qnil;

-DWORD CallbackFunction(PARAM param)
+DWORD CallbackFunction(void* fptr,PARAM param)
 {
     VALUE v_proto, v_return, v_proc, v_retval;
     VALUE argv[16];
     int i, argc;
     char *a_proto;
     char *a_return;
+    VALUE ActiveCallback;

+    ActiveCallback = rb_hash_aref(CallbackTable,INT2NUM((DWORD)fptr));
     if(!NIL_P(ActiveCallback)){
         v_proto = rb_iv_get(ActiveCallback, "@prototype");
         a_proto = RSTRING(v_proto)->ptr;
@@ -547,6 +549,43 @@
     return 0;
 }

+DWORD CallbackFunction1(PARAM param)
+{
+    return CallbackFunction(CallbackFunction1,param);
+}
+DWORD CallbackFunction2(PARAM param)
+{
+    return CallbackFunction(CallbackFunction2,param);
+}
+DWORD CallbackFunction3(PARAM param)
+{
+    return CallbackFunction(CallbackFunction3,param);
+}
+DWORD CallbackFunction4(PARAM param)
+{
+    return CallbackFunction(CallbackFunction4,param);
+}
+DWORD CallbackFunction5(PARAM param)
+{
+    return CallbackFunction(CallbackFunction5,param);
+}
+DWORD CallbackFunction6(PARAM param)
+{
+    return CallbackFunction(CallbackFunction6,param);
+}
+DWORD CallbackFunction7(PARAM param)
+{
+    return CallbackFunction(CallbackFunction7,param);
+}
+DWORD CallbackFunction8(PARAM param)
+{
+    return CallbackFunction(CallbackFunction8,param);
+}
+
+static void *CallbackArray[] = {CallbackFunction1,CallbackFunction2,
+       CallbackFunction3,CallbackFunction4,CallbackFunction5,CallbackFunction6,
+       CallbackFunction7,CallbackFunction8};
+
 /*
  * call-seq:
  *    Win32::API#call(arg1, arg2, ...)
@@ -563,7 +602,7 @@
    VALUE v_proto, v_args, v_arg, v_return;
    Win32API* ptr;
    unsigned long return_value;
-   int i = 0;
+   int i,j;

    struct{
       unsigned long params[16];
@@ -618,8 +657,17 @@
                }
                break;
             case _T_CALLBACK:
-               ActiveCallback = v_arg;
-               param.params[i] = (LPARAM)CallbackFunction;
+                if(CallbackTable==Qnil) CallbackTable = rb_hash_new();
+                for(j=0;j<8;j++) {
+
if(rb_hash_aref(CallbackTable,INT2NUM((DWORD)CallbackArray[j]))==Qnil)
{
+                    param.params[i] = (LPARAM)CallbackArray[j];
+
rb_hash_aset(CallbackTable,INT2NUM((DWORD)CallbackArray[j]),v_arg);
+                     break;
+                   }
+                   if(j==7) {
+                       rb_raise(rb_eArgError,"Callback function table
overflow");
+                   }
+                }
                break;


I'm not sure this will fix segfault in test suite, but it will fix
multiple callback handling problem.
Here is test code

      require 'win32/api'
      include Win32

      api_ew   = API.new('EnumWindows', 'KP', 'L', 'user32')
      api_gwt  = API.new('GetWindowText', 'LPI', 'I', 'user32')

      callback1 = API::Callback.new('LP', 'I'){ |handle, param|
         	buf = "\0" * 200
         	p "CALLBACK1"
            api_gwt.call(handle, buf, 200);
           buf.index(param).nil? ? true : false
      }
      callback2 = API::Callback.new('LP', 'I'){ |handle, param|
         	buf = "\0" * 200
         	p "CALLBACK2"
            api_gwt.call(handle, buf, 200);
           buf.index(param).nil? ? true : false
      }

      a = Thread.new {
         api_ew.call(callback1, 'UEDIT32')
      }
      b = Thread.new {
         api_ew.call(callback2, 'UEDIT32')
      }
      a.join
      b.join


Regards,

Park Heesob


More information about the win32utils-devel mailing list