/* Borland C */
#if (defined(__BORLANDC__) && __BORLANDC__ >= 452)
#define ASM_LOAD_EAX(param,type) { \
^
|-- THIS IS AN UNMATCH BRACE
__asm { \
mov eax, type param ; \
push eax ; \
}
/* MSVC compilers */
#elif defined _MSC_VER
But...in the resultant .c file after XS preprocessing the effect is that the apparent closing brace of the Call function:
#line 841 "API.c"
PUTBACK;
return;
}
} <-----------THIS MATCHES THE EXTRA OPEN BRACE ABOVE>
matches up with that conditionally compiled excess open brace above.
And if you delete the excess brace, the closing brace of the Call function:
#line 837 "API.c"
PUTBACK;
return;
}
} <-------------THIS ONE
Now no longer matches anything. The second to last closing brace (the line above) matches the open brace of the Call function. Quite how that succeeds in compiling is a mystery to me.
The upshot (so far) is that the function USPS4CB is being called successfully and the return parameters are being stacked successfully. But when the Call function attempts to return to the Perl code, the stack violation occurs. The changes that have been made recently (for compatibility with Strawberry Perl?) seem to have royally screwed things.
Beyond that, the problem is shrouded in the mysteries of XS preprocessing which is beyond my frustration level. Now I'm off to relocate a copy of Win32::API 0.41 that works. The simplest alternative I can offer is a C program callable with backticks. See the comment at the bottom for build instructions and sample usage:
[0] Perl> print `663116.exe 30702021202000000001 27203643012`;;
ATTDAATFADDDTDDTFTFFADADFDTDDAFTATTAAATAAFTFADFDTTTFADAFDDATDDTFT
The C source: #include <stdio.h>
#include <windows.h>
typedef int (*USCS4CB)( char t[21], char r[12], char b[66] );
int main(int argc, char *argv[]) {
HINSTANCE hinstLib;
USCS4CB fp;
char track[21];
char route[12];
char bar[66];
int rc;
if( argc != 3 ) {
fprintf( stderr, "usage: %s trackcode(20) routecode(11)\n", ar
+gv[0] );
exit( -3 );
}
if( hinstLib = LoadLibrary( TEXT("usps4cb") ) ){
if( !( fp = (USCS4CB) GetProcAddress( hinstLib, "USPS4CB" ) )
+) {
fprintf( stderr,
"Couldn't obtain proc addr for USCS4CB(); rc:%x\n",
GetLastError()
);
exit( -5 );
}
}
else {
fprintf( stderr, "Couldn't load USCS4CB.dll; rc %x\n", GetLast
+Error() );
exit( -4 );
}
if( strlen( argv[ 1 ] ) != 20 ) {
fprintf( stderr, "Param 1 (Track code) not 20 digits\n" );
exit( -1 );
}
memcpy( track, argv[1], 20 );
track[20] = '\0';
if( strlen( argv[ 2 ] ) != 11 ) {
fprintf( stderr, "Param 2 (Route code) not 11 digits\n" );
exit( -2 );
}
memcpy( route, argv[2], 11 );
route[11] = '\0';
memset( bar, 0, sizeof( bar) );
if( rc = (fp)( track, route, bar ) ) {
fprintf( stderr, "USPS4CB failed with rc:%d\n", rc );
exit( rc );
}
printf( bar );
return 0;
}
/*
C:\test>cl 663116.c
Microsoft (R) 32-bit C/C++ Standard Compiler Version 13.00.9466 for 80
+x86
Copyright (C) Microsoft Corporation 1984-2001. All rights reserved.
663116.c
Microsoft (R) Incremental Linker Version 7.00.9466
Copyright (C) Microsoft Corporation. All rights reserved.
/out:663116.exe
663116.obj
C:\test>.\663116
usage: .\663116 trackcode(20) routecode(11)
C:\test>.\663116 3070202120200000001 27203643012
Param 1 (Track code) not 20 digits
C:\test>.\663116 30702021202000000001 2720364302
Param 2 (Route code) not 11 digits
C:\test>.\663116 30702021202000000001 27203643012
ATTDAATFADDDTDDTFTFFADADFDTDDAFTATTAAATAAFTFADFDTTTFADAFDDATDDTFT
*/
Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
"Science is about questioning the status quo. Questioning authority".
In the absence of evidence, opinion is indistinguishable from prejudice.
|