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!

+2


source to share


3 answers


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.

+2


source


See how swig does it . Maybe you will find your answer there.



0


source


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.

0


source







All Articles