How can I call Win32 DLL void ** parameter using Win32 :: API?
I have a Windows DLL that I want to call from Perl. The exported function is prototype:
int __stdcall func(const char*, int, int, int, double, double, void**);
The last parameter returns a pointer to the object allocated in the function.
Perl code -
my $dll_path = "../stage/test_dll.dll";
my $dll_func = new Win32::API($dll_path,
'func',
'PIIIDDP', 'I');
my $data = "test something here";
my $pResult = 0;
my $rc = $ dll_func ->Call($data, 0, 0, 9, 0.6, 0.3, $pResult);
An error message appeared stating that the recording could not be written. Maybe I can't use P to represent void **? I read all the documentation and couldn't find one example that uses the void ** parameter. Help!
The variable associated with the parameter P
must be the specified string variable, not an integer. Try something like:
my $pResult = "\0" x 8; # Just in case we're 64-bit
my $rc = $ dll_func ->Call($data, 0, 0, 9, 0.6, 0.3, $pResult);
$pResult
will contain a pointer to the object. You will probably need to use unpack
to extract it.
You don't say what you need to do with the object. If you need to pass it to other DLL functions like void*
, you probably have to unpack it like long
and use it N
instead P
in the parameter list.
source to share
This answer may not be active, but the module Inline::C
offers a pretty good interface in user libraries, and inside Perl and C, you can find all sorts of workarounds for passing data using a pointer void**
.
use Inline C => DATA => LIBS => '-L../stage -ltest_dll';
my $data = "test something here";
my $rc = func_wrapper($data, 0, 0, 9, 0.6, 0.3);
my $p = get_pointer();
printf "func() set a pointer value of 0x%x\n", $p;
__END__
__C__
#include <stdio.h>
int func(const char *, int, int, int, double, double, void **);
void* pointer_value;
long get_pointer()
{
return (long) pointer_value;
}
/*
* Wraps func() in test_dll library.
*/
int func_wrapper(const char *s, int i1, int i2, int i3, double d1, double d2)
{
void *p = (void *) "some pointer";
int rval = func(s, i1, i2, i3, d1, d2, &p);
/* func() may have changed p as a side effect */
/* for demonstation, save it to a long value that can be retrieved with
the get_pointer() function. There are other ways to pass the pointer
data into Perl. */
pointer_value = p;
printf("The pointer value from func() is %p\n", p);
return rval;
}
If Inline :: C interests you, the Inline :: C-Cookbook page on CPAN is also irreplaceable.
source to share