Call function in the C built-in library

I am trying to make a simple wrapper around the CommonMark C library using Inline :: C. I installed libcmark.so in /usr/local/lib/ .

My current code is as follows:

 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; 

When using the commonmarker from the script, I get:

 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 

I assume that my call to cmark_markdown_to_html does not match its signature, but all the signatures for cmark_markdown_to_html that I found look like this:

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

I have not touched either C or Inline :: C before that, so I probably missed something.

+5
source share
2 answers

The docs do not mention LIBS . The option is called 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__ 

Note that using char* thetext as an argument to an XS function is a sure sign of an error. This gives you a pointer to a string buffer without telling you the format of the buffer.

Assuming the library accepts and returns text encoded using 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; } 

Optimized a little (since newSVpvn_flags less scalar more efficient because it has a code-code with the code 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); } 
+4
source

The -l argument looks suspicious. Usually the compiler / linker will have the prefix "lib" and the suffix ".so", so usually you just need to put

 -lcmark 
+2
source

Source: https://habr.com/ru/post/1209384/


All Articles