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

如何在Python C扩展中获取C类型大小并传入编译参数?

Python C扩展中获取C类型大小的解决方案

Python 没有像 Ruby mkmf 或 Autoconf 的 AC_CHECK_SIZEOF 那样直接内置的类型大小检测方法,但可以基于 distutils/setuptools 的编译能力自行实现,核心逻辑是编译一段测试代码并运行以获取目标类型的 sizeof 值。

实现步骤

1. 编写类型大小检测函数

在 setup.py 中添加一个函数,利用 distutils.ccompiler 编译并运行测试代码:

from distutils.ccompiler import new_compiler
import os
import subprocess

def get_sizeof_type(type_name, include_headers=None):
    include_headers = include_headers or []
    compiler = new_compiler()
    
    # 构建测试代码,包含必要的头文件
    header_lines = "\n".join([f"#include <{hdr}>" for hdr in include_headers])
    test_code = f"""{header_lines}
#include <stdio.h>

int main() {{
    printf("%zu", sizeof({type_name}));
    return 0;
}}
"""
    
    # 写入临时测试文件
    temp_c = "sizeof_temp.c"
    with open(temp_c, "w") as f:
        f.write(test_code)
    
    try:
        # 编译测试程序
        obj_files = compiler.compile([temp_c])
        exe_file = compiler.link_executable(obj_files, "sizeof_temp")
        
        # 运行程序并捕获输出
        size_output = subprocess.check_output([exe_file]).decode().strip()
        return int(size_output)
    finally:
        # 清理临时文件
        for f in [temp_c] + obj_files + [exe_file]:
            if os.path.exists(f):
                os.remove(f)

2. 在setup中使用检测结果

调用上述函数获取类型大小,再传入编译参数:

from setuptools import setup, Extension

# 替换为你需要检测的类型和对应的头文件
sizeof_mytype = get_sizeof_type("MyType", include_headers=["mytype.h"])

setup(
    name="my_c_extension",
    ext_modules=[
        Extension(
            "my_c_extension",
            sources=["my_extension.c"],
            extra_compile_args=[f"-DSIZEOF_MYTYPE={sizeof_mytype}"]
        )
    ]
)

关键注意事项

  • 如果检测的是自定义类型(如你示例中的 MyType),必须通过 include_headers 参数传入对应的头文件,否则编译会失败。
  • 使用 %zu 作为 printf 的格式符是 C 标准写法,适配大多数现代编译器和平台(包括32位/64位系统)。
  • 临时文件清理逻辑确保不会在项目目录留下编译残留,避免干扰后续构建。

内容的提问来源于stack exchange,提问作者jjg

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.29 04:53:13