----------------------------------------
> Date: Fri, 11 May 2012 10:08:02 +0200
> From: d...@perl.it
> To: bul...@hotmail.com
> CC: cos...@streppone.it; libwin32@perl.org
> Subject: Re: 3 Win32::API bugs
>
> as you may have realized, Win32::API::Callback is pure evil :-)
>
> I wouldn't spend too much time on it, it has always been more of a proof
> of concept than real working code. as the documentation goes, "highly
> experimental". I don't know of any code (or CPAN module) that relies on
> callbacks. good that you fixed some of the awkwardness, but I'm afraid
> the whole concept is too fragile to be *really* fixed.
I wouldn't say the concept is evil at all. .NET does something similar I think
for its bytecode interpreter. Its just the current implementation of ::Callback
is too complicated and too flawed by trying to manipulate a function that was
made by arbitrary compiler. Hard coding the whole func in hex constants/string,
would be more reliable. Or having the "section" asm strings be hard coded, not
chopped up from a compiler. From the last time I looked at GCC asm, it doesn't
ever use push/pop anyway by default, instead it does movs onto ebp+ or esp+. If
I tried to write ::Callback, I would have just a asm function template with 1
void * 0xCODE pointer (a ::Callback SVHV or SVRV, or a SVPV off the HV or the
PV of a SVPV of a HV) , and pass that 0xCODE and the value of original incoming
ESP to a pure C func, then parse C stack in pure C. In theory you could just do
& on one and only auto var C func and that pointer is kindda the stack bottom
(numeric top). The only thing you can't do from C absolutely is set the stack
unwind amount. This design is much simpler design, and probably much easier to
make x64 compatible than the asm function spliting, parsing, then pasting
nightmare right now. Stack unwind info on x64 would need to be made dynamically
for ::Callback to be x64 compatible. With section pasting, the unwind info
would be harder to generate and register with windows. If there is a glaring
problem with my "a better ::Callback" idea, its because I read ASM alot more
than write it. I'm not rewriting ::Callback. I got it working "enough" as I
described earlier.
My next problem is, pointerCallPack which calls Win32::API::Type::Pack and
pointerCallUnpack which calls Win32::API::Type::UnPack do nothing. They are
G_DISCARD, and Win32::API::Type::Pack and Win32::API::Type::UnPack dont change
their parameters in place, so the un/pack they did on copy of $_[1] ($arg) is
tossed. Is this a bug or a broken feature?
from XS Win32::API::Call
__________________________
case T_POINTER:
params[i].t = T_POINTER;
origST[i] = ST(i+1);
if(has_proto) {
if(SvOK(ST(i+1))) {
pointerCallPack(aTHX_ ST(i+1), i, intypes);
params[i].p = (char *) SvPV_nolen(ST(i+1));
/* When arg is undef, use NULL pointer */
} else {
params[i].p = NULL;
}
} else {
____________________________
For a LPHANDLE prototype (specifically "BOOL __stdcall GetHandle(LPHANDLE
pHandle)", WIn32::API::Type::Pack got $_[0] = 'LPHANDLE' and $_[1] was the
argument from the test script call to Call(). For all the pointers to
numbers/pointers/integers, Win32::API seems to require null padding and
unpacking the PV string yourself. Is this by design (pointerCallPack is
redundant and should be removed), or is this a bug (WIn32::API::Type::Pack the
result of pack() should be assign to $_[1])?
Right now I'm thinking of implementing a sub VERSION for Win32::API to turn on
unsigned and change S to short and struct to T and get
WIn32::API::Type::Un/Pack updating their @_ params and whatever other
compatibility breaking features/bugs I find in the next couple days. I know
you said the letters dont mean anything, but I believe they are directly
related to and are fed to the pack command.