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

如何实现C++ vector函数与Python的ctypes跨语言绑定?

解决ctypes调用C++ std::vector操作函数的问题

extern "C"仅支持C语言原生类型,std::vector是C特有的模板容器,C编译器无法识别其类型,且C模板函数的名字修饰规则与C不兼容,导致无法被ctypes正确识别和调用。因此不能直接把std::vector作为extern "C"函数的参数或返回值,以下是两种可行的解决方法:

方案1:用C兼容的数组+长度替代vector

这是最简单直接的方案,将vector操作转换为C风格数组操作,完全避开C++特有类型。

C++代码(vecadd.cpp)

#include <vector>
#include <algorithm>

// 导出C风格接口
extern "C" {
    void add_to_array(int* arr, int len, int n) {
        // 若已有基于vector的业务逻辑,可先将数组转为vector处理
        std::vector<int> vec(arr, arr + len);
        std::for_each(vec.begin(), vec.end(), [n](int& num) { num += n; });
        // 将结果写回原数组
        std::copy(vec.begin(), vec.end(), arr);
    }
}

编译为动态库

Linux/macOS:

g++ -shared -fPIC -o libvecadd.so vecadd.cpp

Windows:

g++ -shared -o vecadd.dll vecadd.cpp

Python调用代码

import ctypes

# 加载动态库
lib = ctypes.CDLL('./libvecadd.so')  # Windows环境替换为'./vecadd.dll'

# 声明函数参数类型
lib.add_to_array.argtypes = (ctypes.POINTER(ctypes.c_int), ctypes.c_int, ctypes.c_int)
lib.add_to_array.restype = None

# 测试数据
nums = [12, 10, 2, 14]
n = 2

# 将Python列表转为C兼容数组
arr = (ctypes.c_int * len(nums))(*nums)

# 调用函数
lib.add_to_array(arr, len(nums), n)

# 转换回Python列表
result = list(arr)
print(result)  # 输出: [14, 12, 4, 16]

方案2:封装vector为不透明指针(void*)

若必须保留std::vector的使用,可将其包装为void*传递,导出一组C风格函数完成创建、操作、销毁的全流程。

C++代码(vecwrapper.cpp)

#include <vector>
#include <algorithm>

extern "C" {
    // 创建空的vector<int>,返回不透明指针
    void* create_int_vector() {
        return new std::vector<int>();
    }

    // 向vector添加元素
    void vector_push_back(void* vec_ptr, int val) {
        auto* vec = static_cast<std::vector<int>*>(vec_ptr);
        vec->push_back(val);
    }

    // 给vector所有元素加指定数值
    void vector_add_n(void* vec_ptr, int n) {
        auto* vec = static_cast<std::vector<int>*>(vec_ptr);
        std::for_each(vec->begin(), vec->end(), [n](int& num) { num += n; });
    }

    // 获取vector长度
    int vector_size(void* vec_ptr) {
        auto* vec = static_cast<std::vector<int>*>(vec_ptr);
        return vec->size();
    }

    // 获取vector指定位置的元素
    int vector_get(void* vec_ptr, int index) {
        auto* vec = static_cast<std::vector<int>*>(vec_ptr);
        return (*vec)[index];
    }

    // 销毁vector,释放内存
    void destroy_vector(void* vec_ptr) {
        delete static_cast<std::vector<int>*>(vec_ptr);
    }
}

编译为动态库

使用与方案1相同的编译命令,生成libvecwrapper.so或vecwrapper.dll

Python调用代码

import ctypes

lib = ctypes.CDLL('./libvecwrapper.so')

# 声明各函数的参数与返回类型
lib.create_int_vector.argtypes = ()
lib.create_int_vector.restype = ctypes.c_void_p

lib.vector_push_back.argtypes = (ctypes.c_void_p, ctypes.c_int)
lib.vector_push_back.restype = None

lib.vector_add_n.argtypes = (ctypes.c_void_p, ctypes.c_int)
lib.vector_add_n.restype = None

lib.vector_size.argtypes = (ctypes.c_void_p,)
lib.vector_size.restype = ctypes.c_int

lib.vector_get.argtypes = (ctypes.c_void_p, ctypes.c_int)
lib.vector_get.restype = ctypes.c_int

lib.destroy_vector.argtypes = (ctypes.c_void_p,)
lib.destroy_vector.restype = None

# 操作流程
vec_ptr = lib.create_int_vector()
try:
    # 添加元素
    for num in [12, 10, 2, 14]:
        lib.vector_push_back(vec_ptr, num)
    # 执行加操作
    lib.vector_add_n(vec_ptr, 2)
    # 获取结果
    size = lib.vector_size(vec_ptr)
    result = [lib.vector_get(vec_ptr, i) for i in range(size)]
    print(result)  # 输出: [14, 12, 4, 16]
finally:
    # 必须销毁vector,避免内存泄漏
    lib.destroy_vector(vec_ptr)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.22 08:16:02