使用NativeCall调用md4c库md_parse函数的最小正确代码
问题根因
调用md_parse直接崩溃退出是因为NativeCall绑定的函数签名、传入参数完全不符合md4c的接口规范:
md_parse的C接口实际需要4个入参,你的代码只传了3个,缺失最后一个用户自定义数据指针参数- 第三个参数要求是填充完所有回调函数指针的MD_PARSER结构体指针,传入空指针会直接触发段错误,程序被系统直接杀死,没有任何报错输出
- 参数类型不匹配:md4c的输入长度参数是无符号32位整型,不是有符号int32。
最小可运行实现
先确认系统已经正确安装md4c动态库,运行以下代码即可正常完成调用,后续打印语句可正常执行:
use v6.d; use NativeCall; # 对应C侧MD_PARSER结构体,字段顺序、类型必须严格对齐 class MD_PARSER is repr('CStruct') { has uint32 $.abi_version; has uint32 $.flags; has Pointer $.enter_block; has Pointer $.leave_block; has Pointer $.enter_span; has Pointer $.leave_span; has Pointer $.text; has Pointer $.debug_log; } # 空回调实现,所有回调直接返回0代表处理成功,避免空指针调用 sub enter-block(Pointer, Pointer) returns int32 { 0 } sub leave-block(Pointer, Pointer) returns int32 { 0 } sub enter-span(Pointer, Pointer) returns int32 { 0 } sub leave-span(Pointer, Pointer) returns int32 { 0 } sub process-text(Pointer, uint32, Pointer) returns int32 { 0 } sub debug-log(Pointer, Str, Pointer) returns int32 { 0 } # 正确的md_parse绑定签名 sub md_parse(Str, uint32, MD_PARSER, Pointer) is native('md4c') returns int32 { * } # 初始化解析器结构体,填充所有必填字段 my $parser = MD_PARSER.new( abi_version => 0, flags => 0, enter_block => &enter-block, leave_block => &leave-block, enter_span => &enter-span, leave_span => &leave-span, text => &process-text, debug_log => &debug-log, ); # 发起调用,不需要用户数据时最后一个参数传空指针 my $res = md_parse('hello', 5, $parser, Pointer); say "解析调用返回码: $res"; say 'hi';
代码运行后会先输出返回码0(代表解析成功),再输出'hi',不会出现静默退出的问题。如果需要实际处理Markdown解析出的节点、文本内容,只需要把对应空回调替换成自己的业务逻辑即可。
内容的提问来源于stack exchange,提问作者StevieD
相关产品推荐
相关产品推荐

