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

Python向C共享库传递的指针被截断为32位问题求助

解决思路

1. 先排查共享库的编译位数

64位环境下如果编译时误加了-m32选项,生成的是32位共享库,64位Python调用时必然会出现指针截断。用命令验证:

file ./libptr_test.so

正常64位库会输出ELF 64-bit LSB shared object,如果显示32位,重新编译时去掉-m32,用标准命令:

gcc -shared -fPIC -o libptr_test.so ptr_test.c

2. 修正C代码的指针打印格式符

你用%x打印64位指针,本身就会截断低32位——%x是32位无符号十六进制格式符,64位环境下要改用%p(标准指针格式,自动适配位数)或者%lx(64位无符号十六进制):

#include <stdio.h>
#include <stdint.h>

void ptr_test(uint32_t *ptr)
{
    printf("ptr_test: ptr =  %p\n", (void*)ptr);
    // 或者用%lx显式打印64位地址
    // printf("ptr_test: ptr = 0x%lx\n", (uint64_t)ptr);
}

3. 调整Python代码的指针传递逻辑

你的Python代码里tbuf1[0].ctypes.data_as(POINTER(c_uint32))属于冗余操作,tbuf1本身就是二维数组,直接取整个数组的指针更准确,避免索引操作可能带来的类型隐式转换问题:

import ctypes
import numpy as np

PTR_TEST = ctypes.CDLL('./libptr_test.so')
ptr_test = PTR_TEST.ptr_test
ptr_test.restype = None
ptr_test.argtypes = [ctypes.POINTER(ctypes.c_uint32)]

tbuf1 = np.empty((1,1), dtype=ctypes.c_uint32)
# 用016X完整显示64位地址
print("tbuf1 at 0x{:016X}".format(tbuf1.ctypes.data))

# 直接传递数组的指针
ptr_test(tbuf1.ctypes.data_as(ctypes.POINTER(ctypes.c_uint32)))

del(PTR_TEST)

4. 验证ctypes类型匹配的正确性

虽然你已经设置了argtypes,可以换用c_void_p简化测试:把C函数改成void ptr_test(void *ptr),Python里设置ptr_test.argtypes = [ctypes.c_void_p],直接传递tbuf1.ctypes.data(整数类型的地址),这样可以排除指针类型不匹配的潜在问题。

5. 用C程序验证共享库本身

写个极简C测试程序,确认共享库在纯C环境下工作正常:

#include <stdio.h>
#include <stdint.h>

void ptr_test(uint32_t *ptr);

int main() {
    uint32_t buf[1][1];
    printf("C test: buf at 0x%lx\n", (uint64_t)buf);
    ptr_test(&buf[0][0]);
    return 0;
}

编译运行:

gcc -o test_lib test_lib.c ./libptr_test.so
./test_lib

如果这里地址显示完整,说明问题出在Python调用环节;如果同样截断,那共享库编译肯定有问题。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.27 22:23:09