сложность возврата строки из вызова функции dll с использованием импорта Win32 :: API в Perl - PullRequest
0 голосов
/ 28 февраля 2011

Функция такая, 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 Ответ

1 голос
/ 28 февраля 2011

DWORD - это просто тип "long", и Win32::API не будет преобразовывать такое возвращаемое значение.Если ваша функция возвращает char *, просто объявите ее прототип как char* MyFunction(...).

Или используйте один из множества псевдонимов для указателя на символ, которые уже определены в Win32::API::Type.


Редактировать: Это действительно так же просто, как установить прототип, который возвращает 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";

Если у вас возникли проблемыРеплицируя этот пример, начните с чего-то простого - тривиальной функции, которая не принимает аргументов и, например, возвращает целое число, - и сначала запустите ее.Проверяйте $! и $^E на каждом шаге.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...