使用Perl中的Win32 :: API导入从dll函数调用返回字符串的困难

时间:2011-02-28 09:23:02

标签: windows perl winapi

功能如下,string MyFuntion(long,long*)
所以我尝试了很多东西,但没有得到字符串返回 请帮帮我。

Win32::API->Import('My.dll','DWORD MyFunction(long a,long* b)')or die $^E;  
my $var = MyFunction(1,0);  
printf "%d : '%s'\n", length($var),$var;  

1 个答案:

答案 0 :(得分:1)

DWORD只是一个“long”类型,Win32::API不会对此类返回值进行任何转换。如果您的函数返回char *,只需将其原型声明为char* MyFunction(...)

或者使用许多别名中的一个指向已在Win32::API::Type中定义的char的指针。

<小时/>

编辑:这就像设置返回char *的原型一样简单。复杂的部分是创建一个DLL,导出您(和Win32::API)期望它的功能。例如,这个代码创建自己的DLL,然后通过Win32 :: API导入并调用它的函数,在我的系统上工作(Strawberry Perl 5.12.0):

$STRAWBERRY = "C:/strawberry512";  # YMMV

unlink "my_func.dll";

open DLL_SRC, '>', 'my_func.c';
print DLL_SRC q!
#include <stdlib.h>
#include <stdio.h>
#include <windows.h>

char* WINAPI MyFunc(int a, int b)
{
    char *s = (char *) malloc(32);
    if (a==0 && b==0) {
        strcpy(s, "JAPH");
    } else {
        s[0] = 32 + (a % 64);
        s[1] = 32 + (b % 64);
        s[2] = '\0';
    }
    return(s);
}
!;
close DLL_SRC;

open DLL_DEF, '>', 'my_func.def';
print DLL_DEF "EXPORTS\nMyFunc\@8\n";
close DLL_DEF;

system("$STRAWBERRY/c/bin/gcc.exe", "-c", "my_func.c") ||
system("$STRAWBERRY/c/bin/gcc.exe", 
       "-mdll",
       "-o", "junk.tmp",
       "-Wl,--base-file,my_func.tmp", "my_func.o") ||
system("$STRAWBERRY/c/bin/dlltool",
       "--dllname", "my_func.dll",
       "--base-file", "my_func.tmp",
       "--output-exp", "my_func.exp",
       "--def", "my_func.def", "-k") ||
system("$STRAWBERRY/c/bin/gcc",
       "-mdll",
       "-o", "my_func.dll",
       "my_func.o",
       "-Wl,my_func.exp") ||
print "my_func.dll seems to have created successfully.\n\n";

use Win32::API;
Win32::API->Import('my_func', 
                   'char* MyFunc(int a, int b)') or die $!,$^E;
$val = MyFunc(0,0);
print $val;
print MyFunc(1,65);
unlink "my_func.dll", "libmy_func.a", "my_func.def",
   "my_func.o", "my_func.exp", "my_func.tmp", "my_func.c";

如果你在复制这个例子时遇到了麻烦,那就从简单的东西开始 - 一个不带args的简单函数,例如返回一个整数 - 然后让它先工作。每一步都检查$!$^E