Criando uma estrutura C estática contendo seqüências de caracteres
Estou tentando criar uma biblioteca dinâmica no Rust que exporta uma estrutura como um símbolo que será carregado em um programa C via dlopen ().
No entanto, eu estava encontrando alguns segfaults ao acessar a segunda string na estrutura, então fiz um pequeno programa de teste para tentar descobrir o que estou fazendo de errado.
Este é o código Rust (test.rs), compilado com "rustc --crate-type dylib test.rs":
#[repr(C)]
pub struct PluginDesc {
name: &'static str,
version: &'static str,
description: &'static str
}
#[no_mangle]
pub static PLUGIN_DESC: PluginDesc = PluginDesc {
name: "Test Plugin\0",
version: "1.0\0",
description: "Test Rust Plugin\0"
};
e aqui está o programa C que tenta carregar a biblioteca (test.c), compilada com "gcc test.c -ldl -o test":
#include <dlfcn.h>
#include <stdio.h>
typedef struct {
const char *name;
const char *version;
const char *description;
} plugin_desc;
int main(int argc, char **argv) {
void *handle;
plugin_desc *desc;
handle = dlopen("./libtest.so", RTLD_LOCAL | RTLD_LAZY);
if (!handle) {
printf("failed to dlopen: %s\n", dlerror());
return 1;
}
desc = (plugin_desc *) dlsym(handle, "PLUGIN_DESC");
if (!desc) {
printf("failed to dlsym: %s\n", dlerror());
return 1;
}
printf("name: %p\n", desc->name);
printf("version: %p\n", desc->version);
printf("description: %p\n", desc->description);
return 0;
}
Esta é a saída:
name: 0x7fa59ef8d750
version: 0xc
description: 0x7fa59ef8d75c
Como você pode ver, o endereço da versão desc-> é na verdade 0xc (12), que é o comprimento da primeira string. Portanto, parece que a estrutura que é compactada na biblioteca também contém o comprimento da sequência após o endereço da memória.
Estou usando o tipo de string errado aqui? Como você pode ver, eu também precisei fazer as seqüências NULL terminadas manualmente. Tentei usar o wrapper CString, mas isso não parece funcionar neste caso ("itens estáticos não podem ter destruidores").
Estou executando o último Rust todas as noites no Linux:
$ rustc --version
rustc 0.12.0-pre-nightly (f8426e2e2 2014-09-16 02:26:01 +0000)