Ich versuche, eine dynamische Bibliothek in Rust zu erstellen, die eine Struktur als Symbol exportiert, das in ein C-Programm geladen wird über dlopen().
Allerdings stieß ich beim Zugriff auf den zweiten String in der Struktur auf einige Segfaults, also habe ich ein kleines Testprogramm erstellt, um herauszufinden, was ich falsch mache.
Das ist der Rust-Code (test.rs), kompiliert mit "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"
};
Und hier ist das C-Programm, das versucht, die Bibliothek zu laden (test.c), kompiliert mit "gcc test.c -ldl -o test":
#include
#include
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;
}
Das ist die Ausgabe:
name: 0x7fa59ef8d750
version: 0xc
description: 0x7fa59ef8d75c
Wie man sieht, ist die Adresse von desc->version tatsächlich 0xc (12), was die Länge des ersten Strings ist. Es scheint also, dass die Struktur, die in die Bibliothek verpackt wird, auch die Zeichenfolgenlänge nach der Speicheradresse enthält.
Verwende ich hier den falschen Zeichenfolgentyp? Wie man sehen kann, musste ich die Zeichenfolgen auch manuell mit NULL terminieren. Ich habe versucht, den CString Wrapper zu verwenden, aber das scheint in diesem Fall nicht zu funktionieren ("static items are not allowed to have destructors").
Ich verwende die neueste Rust-Nightly auf Linux:
$ rustc --version
rustc 0.12.0-pre-nightly (f8426e2e2 2014-09-16 02:26:01 +0000)