Torsten Förtsch
IT System Development & Security
Kaum macht man's richtig, schon geht's, ;-)

>> Home >> Tipps & Tricks >> Read-only Variablen in XS

Read-only Variablen in XS

Im Zusammenhang mit meinem MMapDB Modul wollte ich den Speicherbedarf optimieren und dachte, es müsse doch möglich sein, auf einen String, den man auf C-Level in einem read-only Speichersegment hat, in Perl zuzugreifen, ohne ihn zu kopieren.

Normalerweise würde man in XS einen Perl-String folgendermaßen erzeugen:

sv=newSVpv(pointer, length)

Dabei wird allerdings Speicher alloziiert und der String kopiert. Das wollte ich vermeiden.

Nun gibt es im Perl API die Macros SvPV_set, SvLEN_set und SvCUR_set, mit denen man den Pointer, die alloziierte Länge und die aktuelle Länge eines Perl-Strings setzen kann. Da mein String jedoch nicht von Perl alloziiert wurde, mußte ich irgendwie verhindern, daß Perl versucht den String freizugeben, wenn die Variable vom Garbage Collector vernichtet wird. Der Aufruf von Safefree() mußte also verhindert werden.

Das Studium des Perl-Source-Codes ergab, daß eine alloziierte Länge von Null den Safefree-Aufruf verhindert. Der Trick ist also SvLEN_set(sv, 0). Am Ende sah meine Lösung so aus:

sv=newSV(0);
SvUPGRADE(sv, SVt_PV);
SvPOK_only(sv);
SvPV_set(sv, pointer);
SvLEN_set(sv, 0);
SvCUR_set(sv, length);
SvREADONLY_on(sv);

Das lies ich mir von den Machern von Perl auf der perl5-porters Mailing Liste bestätigen. Es wurde auch bestätigt, daß das mit großer Wahrscheinlichkeit auch in zukünftigen Perl-Versionen so bleiben wird.

Letzte Aktualisierung: 12.07.2009