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

Swig无法将numpy.float64转为C++ double引发TypeError求助

SWIG + numpy.vectorize 类型转换问题:numpy.float64 无法传入新增C++函数

问题场景

用SWIG实现Python与C模块绑定,新增C函数后,带@numpy.vectorize装饰的函数在输入numpy.float64类型数组时,调用新函数触发TypeError。测试发现vectorize会先以numpy.float64类型传入数组首个元素(SWIG默认无法转为C++ double),后续元素则以Python float类型传入,旧C++函数可正常处理。

测试代码:

import numpy as np

@np.vectorize
def test(mu):
    print(mu, type(mu))
    
test(np.array([6.2, 67.3]))

输出结果:

6.2 <class 'numpy.float64'>
6.2 <class 'float'>
67.3 <class 'float'>

业务代码问题示例:

import numpy as np
import cpplib

@np.vectorize
def eps(t, mu):
    if t > 0:
        return cpplib.old_func(mu)  # 正常运行
    else:
        return cpplib.new_func(mu)  # 触发TypeError

新旧C函数均为接收double、返回double的签名,头文件、wrap.i及SWIG生成的包装代码未发现明显差异。尝试过NumPy文档建议的复制pyfragments.swg到项目目录,但之前无需此操作且复制后引发编译错误;此前也曾出现该问题,同事无法复现且自行恢复,修复C语法错误无效。


解决方案

1. 给vectorize指定otypes参数强制输出类型

numpy.vectorize的首次类型检测可能因新函数返回值推断异常,明确指定输出类型可让vectorize统一处理输入类型转换:

@np.vectorize(otypes=[np.float64])
def eps(t, mu):
    if t > 0:
        return cpplib.old_func(mu)
    else:
        return cpplib.new_func(mu)

2. 在SWIG接口文件中显式添加类型映射

在wrap.i中添加SWIG类型映射,让其支持numpy.float64到C++ double的转换:

%include "numpy.i"
%init %{
import_array();
%}

// 显式映射numpy.float64到double
%typemap(in) double {
  if (PyFloat_Check($input) || PyArray_CheckScalar($input, NPY_DOUBLE)) {
    $1 = PyFloat_AsDouble($input);
  } else {
    PyErr_SetString(PyExc_TypeError, "Expected a float or numpy.float64");
    return NULL;
  }
}

需先引入numpy.i并初始化numpy的C API(import_array()),确保SWIG能识别numpy标量类型。

3. Python层手动转换输入类型

在vectorize包裹的函数内,先将输入转为Python float再传入C++函数,快速规避类型转换问题:

@np.vectorize
def eps(t, mu):
    mu_float = float(mu)
    if t > 0:
        return cpplib.old_func(mu_float)
    else:
        return cpplib.new_func(mu_float)

4. 排查SWIG生成的包装代码细节

对比旧函数与新函数的SWIG生成代码:

  • 检查新函数的参数处理逻辑,是否缺失对numpy标量的判断
  • 确认SWIG处理新函数时,是否正确应用了项目中已有的numpy类型映射配置

可能的根本原因

旧函数可能因历史配置、SWIG版本差异或缓存的包装代码,自动带上了numpy类型转换逻辑;而新函数未触发该逻辑。加上numpy.vectorize首次调用用numpy.float64做类型测试,新函数的SWIG包装不支持该类型,直接触发报错。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.14 09:40:05