DLL Call Follies

K

Kythe

Hello,
My apologies if this is a rather basic question, but I've been beating
my head against the wall trying to get Win32::API interfacing to a dll
working, and I've never done this before.

The dll in question is proprietary; however, it's 32 bit, it requires a
32,000-byte memory space, and returns values via parameters, not just
via return values.

Here's the documentation in question:

"The calling program must provide a workspace for mydll.dll. mydll will
do most of its processing & storing of data in this workspace.
Currently, the work space must be at least 32k bytes (bigger won't
help). Visual Basic programs must provide this via the Windows memory
allocation API. 'C' or Pascal programs may provide a pointer to a
memory area. Mydll creates pointers within the work space, so if the
memory is relocated, the work space must be re-initialized. This can
happen with any call, and is signaled by an error return on the call.
Error codes are listed in the "Return Error Codes" section of this
document."

Here's the provided calling procedure for Delphi/Pascal:

Procedure InitializeDataBaseDbSrvr( DatabasePath_Ptr, Password_Pchar:
Pchar; WorkSpace_Ptr: Pointer; WorkSpaceSize_Wrd: Word; Var
SizeUsed_Wrd: Word; Var ErrorReturn: SmallInt );

And here's the PERL code as it stands now:

#!c:\perl\bin\perl.exe
$password = 'xxxxxxxx';
$cwd = 'C:\\Program Files\\MyDllWorkingDirectory\\';
$err_return = 0;
$buffersize = 32000;

use Win32::API;
Win32::API::Struct->typedef('BUFFER', qw(BYTE Buffer[32000])) or die
"$!\n";
my $buff = Win32::API::Struct->new('BUFFER');

$initialize = new
Win32::API("mydll.dll","InitializeDataBaseDbSrvr","CCSNP","V");
$initialize->Call($cwd,$password,$buff,$buffersize,$err_return);

print "$err_return\n";

Right now, Perl is throwing an error dialog "Perl Command Line
Interpreter has encountered a problem and needs to close. We are sorry
for the inconvenience."

I'm kind of tapped out on this right now. Like I said, I haven't used
PERL to import dll functions before, and I'm at wall when it comes to
the documentation and sample scripts.

Any help would be most appreciated!
 
J

John Bokma

Kythe said:
32,000-byte memory space, and returns values via parameters, not just
via return values.

Here's the documentation in question:

"The calling program must provide a workspace for mydll.dll. mydll will
do most of its processing & storing of data in this workspace.
Currently, the work space must be at least 32k bytes (bigger won't

32K is probably 32,768 bytes (2^15), not 32,000
 
K

Kythe

John said:
32K is probably 32,768 bytes (2^15), not 32,000

Very true. In the sample code they provide for allocating memory using
the kernel32 function GlobalAlloc, however, they use the nice, round
32,000 bytes. I figured it was probably close enough :)

Even so, using 32,768 doesn't change the outcome.
 
J

John Bokma

Kythe said:
Very true. In the sample code they provide for allocating memory
using the kernel32 function GlobalAlloc, however, they use the nice,
round 32,000 bytes. I figured it was probably close enough :)

Even so, using 32,768 doesn't change the outcome.

Ok, I was guessing that not enough memory caused the behavior you saw but
was not sure :)
 
S

Sisyphus

..
..
And here's the PERL code as it stands now:

#!c:\perl\bin\perl.exe
$password = 'xxxxxxxx';
$cwd = 'C:\\Program Files\\MyDllWorkingDirectory\\';
$err_return = 0;
$buffersize = 32000;

use Win32::API;
Win32::API::Struct->typedef('BUFFER', qw(BYTE Buffer[32000])) or die
"$!\n";
my $buff = Win32::API::Struct->new('BUFFER');

$initialize = new
Win32::API("mydll.dll","InitializeDataBaseDbSrvr","CCSNP","V");
$initialize->Call($cwd,$password,$buff,$buffersize,$err_return);

print "$err_return\n";

You should determine just which line of code is producing the error you
reported. Is it the initial assignment to $buff, the initial assignment to
$initialize, or the '$initialize->Call()' that's causing the error.

I could be miles off ... but what happens if you rewrite that as:

#!c:\perl\bin\perl.exe
$password = 'xxxxxxxx';
$cwd = 'C:\\Program Files\\MyDllWorkingDirectory\\';
$err_return = 0;
$buffersize = 32768;
use Win32::API;

my $buff = " " x $buffersize;

$initialize = new
Win32::API("mydll.dll","InitializeDataBaseDbSrvr","PPPNN","V"); # or maybe
"PPPNP" as 3rd arg
if (not defined $initialize)
{die "Failed to import InitializeDataBaseDbSrvr"}
$initialize->Call($cwd,$password,$buff,$buffersize,$err_return);

print "$err_return\n";

Are you sure that InitializeDataBaseDbSrvr() does not return a value ?

There are some people here who are quite good with Win32::API (though I'm
not one of them). Be patient and you'll probably get a solution.

Cheers,
Rob
 
K

Kythe

Thanks, Rob.

I think I may have found the trouble -- I may have stupidly omitted an
input argument to the function :( At the very least, it looks like
one's missing, and that can't be good.

Figures.

It also sucks that I can't post more details about the dll, but it's a
proprietary, third-party library.

Part of my problem is I've never used Win32::API before, and am not
certain that I'm not making basic, foolish mistakes. But as you said,
I need to spend more time with trial and error on this.
.
.
And here's the PERL code as it stands now:

#!c:\perl\bin\perl.exe
$password = 'xxxxxxxx';
$cwd = 'C:\\Program Files\\MyDllWorkingDirectory\\';
$err_return = 0;
$buffersize = 32000;

use Win32::API;
Win32::API::Struct->typedef('BUFFER', qw(BYTE Buffer[32000])) or die
"$!\n";
my $buff = Win32::API::Struct->new('BUFFER');

$initialize = new
Win32::API("mydll.dll","InitializeDataBaseDbSrvr","CCSNP","V");
$initialize->Call($cwd,$password,$buff,$buffersize,$err_return);

print "$err_return\n";

You should determine just which line of code is producing the error you
reported. Is it the initial assignment to $buff, the initial assignment to
$initialize, or the '$initialize->Call()' that's causing the error.

I could be miles off ... but what happens if you rewrite that as:

#!c:\perl\bin\perl.exe
$password = 'xxxxxxxx';
$cwd = 'C:\\Program Files\\MyDllWorkingDirectory\\';
$err_return = 0;
$buffersize = 32768;
use Win32::API;

my $buff = " " x $buffersize;

$initialize = new
Win32::API("mydll.dll","InitializeDataBaseDbSrvr","PPPNN","V"); # or maybe
"PPPNP" as 3rd arg
if (not defined $initialize)
{die "Failed to import InitializeDataBaseDbSrvr"}
$initialize->Call($cwd,$password,$buff,$buffersize,$err_return);

print "$err_return\n";

Are you sure that InitializeDataBaseDbSrvr() does not return a value ?

There are some people here who are quite good with Win32::API (though I'm
not one of them). Be patient and you'll probably get a solution.

Cheers,
Rob
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,020
Latest member
GenesisGai

Latest Threads

Top