如何使用Win32 :: API调用Win32 DLL void **参数?

我有一个Windows DLL,我想从Perl调用。 导出函数的原型是:

int __stdcall func(const char*, int, int, int, double, double, void**); 

最后一个参数返回一个指向函数中分配的对象的指针。

Perl代码 –

 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); 

popup错误消息,说无法写入内存。 也许我不能用P来表示void **? 我通读了所有的文档,找不到一个使用void **参数的例子。 帮帮我!

P参数关联的变量必须是预先分配的字符串变量,而不是整数。 尝试像这样:

 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将包含指向该对象的指针。 您可能需要使用unpackunpack压缩它。

你不说你需要做什么与对象。 如果您需要将其作为void*传递给其他DLL函数,则可能需要将其解压缩为long整型,然后在参数列表中使用N而不是P

看看如何swig会这样做。 也许你会在那里找到你的答案。

这个答案可能没有基础,但是Inline::C模块为用户库提供了非常好的接口,在Perl和C中,你可以想出各种解决方法来通过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; } 

如果Inline :: C看起来很有趣,那么CPAN上的Inline :: C-Cookbook页面也是不可或缺的。