我试图使用CommonMark C库使用内联::C制作一个简单的包装器。我已经在libcmark.so中安装了/usr/local/lib/。
我的当前代码如下:
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;当从脚本中使用commonmarker时,我得到:
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我假设我对cmark_markdown_to_html的调用与它的签名不匹配,但是对于cmark_markdown_to_html的所有签名--我的找到 --看起来如下所示:
char *cmark_markdown_to_html(const char *text, int len)我以前也没有接触过C或者内联::C,所以我可能遗漏了什么。
发布于 2014-12-17 18:09:33
文档中没有提到LIBS。该选项名为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__请注意,使用char* thetext作为XS函数的参数是bug的一个确定标志。这会给您一个指向字符串缓冲区的指针,而不会告诉您缓冲区的格式。
假设库接受并返回使用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;
}稍微优化一下(因为让newSVpvn_flags死化标量比使用类型地图生成的代码调用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);
}发布于 2014-12-17 18:40:59
您的-l论点看起来令人怀疑。通常编译器/链接器会在"lib“前缀,并将".so”作为后缀,所以通常您只需要提供
-lcmarkhttps://stackoverflow.com/questions/27531950
复制相似问题