[plt-scheme] MysterX and ImageMagick COM object

From: Anton van Straaten (anton at appsolutions.com)
Date: Wed Jul 23 23:38:58 EDT 2003

I found an easy way to get COM vararg calls working with MysterX.  It works
for Ron's example with ImageMagick.  It requires a couple of small changes
to the MysterX C source.  It should have no impact for anything other than
vararg functions.  However, it's definitely a quick fix, it may not handle
all vararg cases (yet), and there's probably a better way to implement it
(but that would require more work).

To avoid having to make more complex changes to deal with type checking in
the vararg case, I introduced a shortcircuit which causes
'buildMethodArgumentsUsingDefaults' to be called when invoking a vararg
function.  This function can handle vararg functions without needing any
changes, so all that's needed is to make sure it gets invoked.  This
required small changes in two places.

I can provide a diff if anyone wants it, but to explain the changes, here's
a description:

In mx_make_call, around line 4235 (ish, my version may slightly be off), I
inserted one line, highlighted with a comment below:

  if (pTypeDesc &&
      (pTypeDesc->funOffset != NO_FUNPTR) &&
      (pTypeDesc->funcdescs.pFuncDesc->cParamsOpt != -1) &&	 // <-- inserted
      /* assignment */
      (retval = mx_make_direct_call(argc,argv,invKind,
				    pIDispatch,name,pTypeDesc))) {
    return retval;
  }

This avoids attempting a direct call through the COM function pointer, when
a vararg function is being invoked.

In addition, the function buildMethodArguments needs its body replaced.  It
previously used the C ternary ?: operator to perform a sequence of tests;
since I needed to embed a further test, this got a bit out of hand, so I
switched it to a nested 'if' statement.  The change here calls
buildMethodArgumentsUsingDefaults if a vararg function is being invoked.
Here's the entire modified function:

short int buildMethodArguments(MX_TYPEDESC *pTypeDesc,
			       INVOKEKIND invKind,
			       int argc, Scheme_Object **argv,
			       DISPPARAMS *methodArguments) {
    if (pTypeDesc == NULL)
    	return buildMethodArgumentsUsingDefaults (invKind, argc, argv,
methodArguments);
    else if (pTypeDesc->descKind == funcDesc)
    	if (pTypeDesc->funcdescs.pFuncDesc->cParamsOpt == -1)
    		return buildMethodArgumentsUsingDefaults (invKind, argc, argv,
methodArguments);
    	else
		return buildMethodArgumentsUsingFuncDesc (pTypeDesc->funcdescs.pFuncDesc,
									 invKind,argc,argv,
									 methodArguments);
	else return buildMethodArgumentsUsingVarDesc (pTypeDesc->pVarDesc,
                                            invKind,argc,argv,
                                            methodArguments);
}

With these changes, Ron's example worked.

Anton



Posted on the users mailing list.