You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Python 3 C API中从str类型PyObject*提取char*?

在Python 3 C API中从str类型PyObject提取char的解决方案

核心结论

Python 3中的str类型对应C API里的PyUnicodeObject,直接用Unicode相关API处理即可,无需转成bytes。

正确操作步骤

  1. 类型校验
    用PyUnicode_Check(obj)判断传入的PyObject*是否为Python 3的str对象。如果你的代码里这个函数匹配不了str(...)创建的对象,大概率是D语言绑定的问题:

    • 确认链接的是Python 3的库而非Python 2
    • 检查D语言对PyUnicode_Check的绑定是否正确,有没有误映射到Python 2的旧API
  2. *提取UTF-8编码的char **
    Python 3的str是Unicode字符串,直接用以下API提取UTF-8格式的char*:

    • PyUnicode_AsUTF8(obj):返回UTF-8编码的const char*,内存由Python管理,不要手动释放
    • PyUnicode_AsUTF8AndSize(obj, &size):同时返回字符串指针和长度,同样无需手动释放内存

示例代码(C语言,D语言可参照调用逻辑)

#include <Python.h>

void process_python_str(PyObject* str_obj) {
    if (!PyUnicode_Check(str_obj)) {
        PyErr_SetString(PyExc_TypeError, "必须传入str类型对象");
        return;
    }

    // 提取字符串(不带长度)
    const char* utf8_content = PyUnicode_AsUTF8(str_obj);
    // 提取字符串(带长度)
    Py_ssize_t str_len;
    const char* utf8_content_with_len = PyUnicode_AsUTF8AndSize(str_obj, &str_len);

    // 使用提取的内容
    printf("字符串内容:%s\n", utf8_content);
    printf("字符串长度:%zd,内容:%.*s\n", str_len, (int)str_len, utf8_content_with_len);
}

关于转bytes的问题

转成bytes再用PyBytes_AsStringAndSize是多此一举,而且会引入编码问题(需要显式指定编码,比如str.encode('utf-8')),直接用Unicode API提取是最直接的方案。如果调用PyBytes_AsStringAndSize报错,就是因为传入的不是bytes对象,这是正常的类型校验结果。

构造可被PyUnicode_Check识别的对象

在C API中,用PyUnicode_FromUTF8("你的字符串")或PyUnicode_FromString("你的字符串")创建的对象,必然能被PyUnicode_Check识别。D语言调用时,要确保调用的是Python 3的这些API,而非Python 2的旧函数。

内容的提问来源于stack exchange,提问作者Nordlöw

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.19 06:40:21