¿Cómo paso los punteros a una DLL usando Win32: API?

votos
2

Estoy tratando de pasar 3 punteros a una función DLL. Yo tengo:

{

$ code = 1;
$ len = 100;
$ str =  x $ len;

$ function = new Win32 :: API (DLLNAME, 'dllfunction', 'PPP', 'V');

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

}

La DLL se define como void dllfunction(int* a, char* str, int* len);La DLL modificará todas las variables apuntadas por los tres punteros.

Sin embargo, estoy segfaulting cuando corro esto. La documentación para Win32 :: API especificó que debería usar el nombre de la variable real en lugar de las referencias a las variables de Perl. ¿Alguien puede decirme lo que me estoy perdiendo? Gracias.

*más información:

Agregué printf()en el DLL para imprimir la dirección de los tres punteros, y printfen Perl para imprimir la referencia de las tres variables. Y obtengo lo siguiente

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

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

¿Alguna idea de por qué el DLL está recibiendo las direcciones incorrectas?

****Más información

Después de mucha depuración, descubrí que esto está sucediendo al regresar de la función DLL. Agregué printf (hecho \ n); como la última línea de esta función DLL, y esta muestra, luego el programa segfaults. Supongo que está sucediendo en Win32 :: API? Alguien ha experimentado esto?

Además, puedo acceder a las variables iniciales de las tres variables de la DLL. Por lo tanto, el puntero se pasa correctamente, pero por alguna razón causa un segfault al regresar de la DLL. Tal vez es segfaulting cuando se trata de copiar los nuevos datos en la variable Perl?

Publicado el 09/12/2008 a las 21:06
fuente por usuario
En otros idiomas...                            


4 respuestas

votos
3

AH !! Me lo imaginé.

El problema fue esto

  1. Y, opcionalmente, puede especificar la convención de llamada, por defecto es '__stdcall', alternativamente puede especificar '_cdecl'.

La función dll se exportó con extern "C" __declspec (dllexport), así que pensé que tal vez debería usar el indicador '_cdecl'.

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

¡trabajos!

gracias a todos.

Respondida el 09/12/2008 a las 23:30
fuente por usuario

votos
0

No soy un programador de Windows pero veo:

para punteros debe usar un nombre de variable

para mí significa los nombres de las variables, no las variables mismas. ¿Esto funciona?

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

o tal vez

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

Por cierto, no esperaría que las direcciones de memoria sean las mismas. Win32::APInecesitará convertir los elementos de datos de Perl en algo que Windows pueda entender y dudo seriamente que ocupen el mismo espacio de memoria física.

Respondida el 09/12/2008 a las 23:08
fuente por usuario

votos
0

OK, seguí el enlace de Adam a esta página . De acuerdo con eso, la llamada debería ser:

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

El código de ejemplo usa una función con un parámetro LPSTR (esencialmente un char *), y usa la variable como era de esperar, pero este bit aquí:

para los punteros debe usar un nombre de variable (sin referencias de Perl, solo un nombre de variable simple).

parece indicar que el código que enumeré en esta publicación debería funcionar.

Respondida el 09/12/2008 a las 22:09
fuente por usuario

votos
0

IANAPH, pero creo que debes usar una referencia , así:

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

El que menos estoy seguro es $ str, puede que no necesite una referencia. Segfault es casi seguro que proviene de la DLL que intenta escribir en la dirección de memoria 1 (o 100, dependiendo de qué intente escribir primero).

Respondida el 09/12/2008 a las 21:31
fuente por usuario

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