Pergunta

Eu estou usando Win32 :: API para chamar uma função arbitrária exportada em uma DLL que aceita a ++ ponteiro estrutura C.

struct PluginInfo {
        int  nStructSize;   
        int  nType;     
        int  nVersion;    
        int  nIDCode;    
        char         szName[ 64 ];  
        char            szVendor[ 64 ];
        int  nCertificate;  
        int  nMinAmiVersion;
};

Como nós precisamos usar a função "pacote" para construir a estrutura e necessidade de passar um argumento

my $name = " " x 64;
my $vendor = " " x 64;
my $pluginInfo = pack('IIIIC64C64II',0,0,0,0,$name,$vendor,0,0);

A sua não é construir a estrutura adequada.
Parece que o argumento comprimento aplicada a C vai devorar aqueles muitos argumentos.
Pode alguém por favor sugerir a melhor maneira de construir esta estrutura de forma Perl e passon a dll chamada.

Agradecemos antecipadamente,
Naga Kiran

Foi útil?

Solução

Use Z (string NUL acolchoado) em seu modelo, como em

my $pluginInfo = pack('IIIIZ64Z64II',0,0,0,0,$name,$vendor,0,0);

Além disso, dê uma olhada Win32::API::Struct , que faz parte do módulo :: API Win32.

Outras dicas

Para qualquer coisa complicada, veja Converter :: Binary :: C . Pode parecer difícil no começo, mas quando você percebe o seu poder, é um abridor de olho.

Update: Deixe-me acrescentar um pouco de informação. Você precisa ter um olhar para um seção específica do manpage do módulo para a principal razão para usá-lo. Vou citá-lo por conveniência:

Por que usar Convert :: Binary :: C?

Digamos que você queira embalar (ou descompactar) dados de acordo com o seguinte C estrutura:

struct foo {
  char ary[3];
  unsigned short baz;
  int bar;
};

Você poderia naturalmente usar pacote de Perl e as funções de descompactação:

@ary = (1, 2, 3);
$baz = 40000;  
$bar = -4711;
$binary = pack 'c3 Si', @ary, $baz, $bar;

Mas isto implica que a struct membros estão alinhados byte. Se eles fossem alinhado de comprimento (que é o padrão para a maioria dos compiladores), você teria que escrever

 $binary = pack 'c3 x S x2 i', @ary, $baz, $bar;

que realmente não aumentar legibilidade.

Agora imagine que você precisa para embalar o dados para uma completamente diferente arquitetura com byte diferente ordem. Você poderia olhar para o pacote Manpage novamente e talvez chegar a isto:

$binary = pack 'c3 x n x2 N', @ary, $baz, $bar;

No entanto, se você tentar descompactar $ foo novamente, seus valores assinados viraram para aqueles não assinados.

Tudo isso pode ainda ser gerido com Perl. Mas imagine suas estruturas de obter mais complexo? Imagine que você precisa suportar diferentes plataformas? Imagine você precisa fazer alterações no estruturas? Você não só tem que alterar a origem C, mas também dezenas de embalar strings em seu código Perl. Esta não é divertido. E Perl deve ser divertido.

Agora, não seria ótimo se você pudesse acabei de ler na fonte C você tem já escrito e usar todos os tipos definido lá para embalagem e desembalar? Isso é o que Converter :: Binary :: C faz.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top