perl crash using Win32::API Call procedure

68 views
Skip to first unread message

Matt

unread,
Mar 8, 2006, 7:32:03 PM3/8/06
to
I'm trying to use the Win32::API module to call a simple test case DLL
(call it "addValues.dll"). My DLL has a function in it called
addValues:

extern "C" __declspec(dllexport)
double addValues(double a, double b) {
double c;
c = a + b;
cout << a << " " << b << " " << c << endl;
return(c);
}

My perl script to call this looks like:

use Win32::API;

$num1 = $ARGV[0];
$num2 = $ARGV[1];

$myFunc =
Win32::API->new('addValues', 'double addValues(double a, double
b)');
$out = $myFunc->Call($num1, $num2);
print "$out";

When executing this, perl bombs at the Call line, giving me the "Perl
Command Line Interpreter has encountered a problem and needs to close.
We are sorry for the inconvenience" message.

Note that if I change my dll function to take no arguments (hard coding
a and b within the function) and return a double, I have no problems,
e.g.

$myFunc = Win32::API->new('addValues', 'double addValues()');
$out = $myFunc->Call();

I have also tried the alternative calling syntax:

$myFunc = Win32::API->new('addValues', 'addValues', 'DD', 'D')

with no success. I'm very likely doing something stupid I know ...

Matt

unread,
Mar 10, 2006, 7:27:02 PM3/10/06
to
A follow-up to this post. The problem was NOT with the Win32::API()
call, but rather with my compiled DLL.

When I had compiled the DLL, I had used the __cdecl calling convention
(In VS .NET 2003, this is the default calling convention). Apparently,
I needed to instead use the __stdcall calling convention which is
required(?) for Win32 API functions (see
http://www.codeproject.com/cpp/calling_conventions_demystified.asp for
reference). You can either set this as a compiler option or explicitly
declare this in your function, eg.

extern "C" __declspec(dllexport)
double __stdcall addValues(double a, double b);

The one change to be careful about is that the function name will be
decorated differently, e.g. the above function becomes _addValues@16 in
the DLL, so the perl script must reflect these changes (use DUMPBIN
with the /EXPORT option to see the export function name).

One thing that I'm still unclear about is that the function name
decoration seems to be required and of the form
"_fxName@{numBytesOfParameters}". Obviously, the functions in
kernel32.dll, etc. do not have this form. Hopefully somebody can clue
me in on this.

Reply all
Reply to author
Forward
0 new messages