如何用ctypes调用apt安装的libunistring库?find_library返回None
ctypes加载libunistring调用
ulc_width_linebreaks实操指南 为什么之前find_library全部返回None
ctypes.util.find_library的入参有固定匹配规则,不支持带lib前缀、版本号、内部组件名、头文件名作为匹配项,你之前的调用全部不符合匹配规则:
- 传入
"libunistring"、"libunistring2":手动加了lib前缀,匹配逻辑不识别这类带前缀的参数 - 传入
"unilbrk":这是libunistring内部的断行组件名称,不是对外导出的动态库名称 - 传入
"unilbrk.h":头文件不属于动态库识别范围,自然无法匹配
正确的库加载步骤
- 先确认系统中库文件的实际位置
终端执行命令查看已注册的libunistring动态库:
安装完对应开发包后,系统路径下会生成供开发使用的无版本号软链ldconfig -p | grep unistringlibunistring.so,默认存放在/usr/lib/x86_64-linux-gnu/目录下。 - 修正
find_library的调用参数
去掉lib前缀后正确的调用为:
如果执行后仍然返回None,直接使用已知的全路径加载即可,不需要依赖find_library的搜索逻辑:from ctypes.util import find_library lib_path = find_library("unistring")import ctypes # 直接通过全路径加载动态库 libunistring = ctypes.CDLL("/usr/lib/x86_64-linux-gnu/libunistring.so")
调用ulc_width_linebreaks的必要配置
ctypes不会自动识别C函数的参数和返回值类型,必须手动完成类型声明,否则会出现段错误、内存越界的问题,按照libunistring的函数原型完成声明:
# 对应ulc_width_linebreaks的C函数原型: # void ulc_width_linebreaks (const char *s, int width, int start_column, int at_interval, # const char *const *ambiguous_width, const char *const *charwidth, # char *linebreaks, int *result_columns) libunistring.ulc_width_linebreaks.restype = None libunistring.ulc_width_linebreaks.argtypes = [ ctypes.c_char_p, # 输入的UTF-8编码字符串指针 ctypes.c_int, # 单行允许的最大显示宽度 ctypes.c_int, # 文本起始的列偏移量 ctypes.c_int, # 间隔断行标记位,常规场景传0即可 ctypes.c_void_p, # 自定义宽字符模糊宽度映射,传None使用默认规则 ctypes.c_void_p, # 自定义单字符宽度映射,传None使用默认规则 ctypes.c_char_p, # 输出缓冲区,存储每个字符位置的断行标记,长度需和输入字符串字节数一致 ctypes.POINTER(ctypes.c_int) # 输出参数,存储文本排版完成后的最终列数 ]
注意事项
- 传入Python字符串时,需要先通过
encode("utf-8")转为字节串,因为ulc系列函数默认处理UTF-8编码的字符流 - 存储断行标记的输出缓冲区必须是可写的预分配内存,不能直接传入不可变的Python bytes对象
内容的提问来源于stack exchange,提问作者user3064538
相关产品推荐
相关产品推荐

