[plt-scheme] MysterX and ImageMagick COM object
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