2014-12-17 17 views
5

Próbuję zrobić proste opakowanie wokół biblioteki C przy użyciu Inline::C. Zainstalowałem libcmark.so w /usr/local/lib/.Funkcja wywoływania w bibliotece Inlined C

Mój bieżący kod wygląda następująco:

package Text::CommonMark; 

use strict; 
use warnings; 

sub commonmarker { 
    my $text = shift; 
    return commonmark_to_html($text); 
} 

use Inline C => qq{ 

    char* commonmark_to_html(char* thetext) { 

     char* result = cmark_markdown_to_html(thetext, strlen(thetext)); 
     return result; 
    } 
} => LIBS => '-L/usr/local/lib/ -llibcmark.so'; 

1; 

Podczas korzystania commonmarker ze skryptu uzyskać:

perl: symbol lookup error: /home/erik/sublimeworks/dists/Text-CommonMark/_Inline/lib/auto/Text/CommonMark_33fb/CommonMark_33fb.so: undefined symbol: cmark_markdown_to_html 

Przypuszczam, że moje wezwanie do cmark_markdown_to_html nie pasuje do jego podpisania, ale wszystko podpisy dla cmark_markdown_to_html, które mam found wyglądają tak:

char *cmark_markdown_to_html(const char *text, int len) 

Nie dotknąłem ani C, ani Inline :: C, więc prawdopodobnie czegoś brakuje.

+1

Tip: Użycie 'q {}' zamiast '' qq {} oznacza, że Muszę uciec znacznie mniej. Co więcej, użycie '<< 'EOC'' oznacza, że ​​nie musisz w ogóle uciekać od czegokolwiek. – ikegami

+1

Nie sądzę, że jest to niedopasowany prototyp. Myślę, że symbol nie został znaleziony w bibliotece lub sama biblioteka nie została znaleziona. 'perl -MInline = force, info, noclean script.pl' może dostarczyć więcej informacji. – ikegami

Odpowiedz

4

Nie wspomniano o LIBS w dokumentacji. Ta opcja nosi nazwę libs.

use Inline C => config => libs => '-L/usr/local/lib/ -llibcmark.so'; 
use Inline C => <<'__EOC__'; 

    char* commonmark_to_html(char* thetext) { 
     char* result = cmark_markdown_to_html(thetext, strlen(thetext)); 
     return result; 
    } 

__EOC__ 

Należy pamiętać, że stosując char* thetext jako argument do funkcji XS jest to pewny znak błędu. To daje wskaźnik do bufora ciągów bez informowania o formacie bufora.

Zakładając biblioteki przyjmuje i tekstu zwroty zakodowany UTF-8

SV* commonmark_to_html(SV* text_sv) { 
    STRLEN text_len; 
    const char* text = SvPVutf8(text_sv, text_len); 
    const char* html = cmark_markdown_to_html(text, text_len); 
    SV* html_sv = newSVpvn_flags(html, strlen(html), SVf_UTF8); 
    free(html); 
    return html_sv; 
} 

zoptymalizowane nieznacznie (od konieczności newSVpvn_flags mortalize skalarna jest bardziej wydajny niż o typemap wygenerowany kod wywołania sv_2mortal):

void commonmark_to_html(SV* text_sv) { 
    STRLEN text_len; 
    const char* text = SvPVutf8(text_sv, text_len); 
    const char* html = cmark_markdown_to_html(text, text_len); 
    SV* html_sv = newSVpvn_flags(html, strlen(html), SVf_UTF8|SVs_TEMP); 
    free(html); 
    ST(0) = html_sv; 
    XSRETURN(1); 
} 
+0

Dzięki! Zgaduję, że powinno być: ... => => config libs => ... ('Nieprawidłowe korzystanie z modułu inline' bez 'libs =>') Wciąż uzyskiwanie ten sam błąd. Mam "LIBS" z Inline :: C :: Cookbook. – Csson

+1

@Csson, Ups, tak, naprawione. Cóż, albo biblioteka nie zawiera symbolu 'cmark_markdown_to_html', albo nie może znaleźć biblioteki. Ten ostatni powinien spowodować pojawienie się ostrzeżenia dla 'perl -MInline = force, info, noclean script.pl'. – ikegami

+0

Dziękuję, działa ładnie! – Csson

2

Twoja argumentacja -l wygląda podejrzanie. Zwykle kompilator/linker prefiks "lib" i Sufiks ".so", więc zazwyczaj należy po prostu trzeba dostarczyć

-lcmark 
+0

To faktycznie działa tak czy inaczej, ale to dobrze wiedzieć. Dzięki! – Csson

Powiązane problemy