Como faço para passar ponteiros para uma DLL usando Win32: API?

votos
2

Eu estou tentando passar em 3 ponteiros para uma função DLL. Eu tenho:

{

$ Code = 1;
$ Len = 100;
$ Str = x $ len;

$ = Função nova Win32 :: API (DLLName, 'dllfunction', 'PPP', 'V');

$ Função-> Call (código $, $ str, $ len);

}

A DLL é definida como void dllfunction(int* a, char* str, int* len);a DLL irá modificar todas as variáveis apontadas pelos três ponteiros.

No entanto, estou segfaulting quando eu executar este. A documentação para Win32 :: API especificado que eu deveria usar o nome de variável real em vez das referências de variáveis Perl. Alguém pode me dizer o que estou ausente? Obrigado.

*Mais Informações:

Eu adicionei printf()na DLL para imprimir o endereço de um dos três ponteiros, e printfem Perl para imprimir a referência das três variáveis. E eu recebo a seguinte

DLL: Código = 0x10107458 erro = 0x10046b50 str = 0x10107460

Perl: Código = 0x101311b8 erro = 0x101312a8 str = 0x10131230

Qualquer idéia de por que a DLL está recebendo os endereços errados?

****Mais Informações

Depois de muita depuração, eu descobri que isso está acontecendo quando voltar da função de DLL. Eu adicionado printf ( feito \ n); como a última linha desta função DLL, e isso faz de saída, em seguida, os segfaults programa. Eu acho que seu acontecimento em Win32 :: API? Alguém já passou por isso?

Além disso, eu sou capaz de acessar as variáveis ​​iniciais de todas as três variáveis ​​a partir da DLL. Assim, o ponteiro é passado corretamente, mas por algum motivo que provoca um segfault quando voltar da DLL. Talvez seja segfaulting ao tentar copiar os novos dados para a variável Perl?

Publicado 09/12/2008 em 21:06
fonte usuário
Em outras línguas...                            


4 respostas

votos
3

AH !! Eu percebi isso.

O problema era este

  1. E, opcionalmente, você pode especificar a convenção de chamada, este padrão é '__stdcall', alternativamente, você pode especificar '_cdecl'.

A função de dll foi exportado com extern "C" __declspec (dllexport) então achei que talvez eu deveria estar usando flag '_cdecl'.

Win32 :: API ( 'DLL', 'dllfunction', 'PPP', 'V', '_ cdecl');

trabalho!

obrigado a todos.

Respondeu 09/12/2008 em 23:30
fonte usuário

votos
0

Eu não sou um programador janelas mas vendo:

para ponteiros você deve usar um nome de variável

para mim significa os nomes de variáveis, não as próprias variáveis. Isto funciona?

$function->Call('code', 'str', 'len');

ou talvez

$function->Call('$code', '$str', '$len');

Btw, eu não esperaria que os endereços de memória a ser o mesmo. Win32::APIserá necessário converter os elementos de dados Perl em algo que o Windows pode entender e eu duvido seriamente que iria ocupar o mesmo espaço de memória física.

Respondeu 09/12/2008 em 23:08
fonte usuário

votos
0

OK, eu segui ligação de Adão para esta página . De acordo com isso, a chamada deve ser:

$function->Call(code, $str, len)

O código de exemplo usa uma função com um parâmetro LPSTR (essencialmente um char *), e usa a variável como seria de esperar, mas isso pouco aqui:

para ponteiros você deve usar um nome de variável (sem referências Perl, apenas um nome de variável simples).

parece indicar que o código que eu listados neste post deve funcionar.

Respondeu 09/12/2008 em 22:09
fonte usuário

votos
0

IANAPH, mas eu acho que você precisa fazer usar uma referência , assim:

$function->Call(\$code, \$str, \$len)

O que eu sou menos certeza sobre é de R $ str - ele pode não precisar de uma referência. O segfault é quase certamente vindo do DLL tentando escrever para o endereço de memória 1 (ou 100, dependendo de qual ele tenta escrever em primeiro lugar).

Respondeu 09/12/2008 em 21:31
fonte usuário

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more