SWIG接口适配问题:Python传递int64类型numpy数组至C++ long函数失败
Hey there! Let's work through why your SWIG setup isn't properly handling that int64 numpy array as a C++ long—I’ve run into similar type-matching headaches before, so here’s what to check and fix:
First, Let’s Clear Up Type Compatibility
The biggest gotcha here is platform-dependent long sizes:
- On Linux/macOS,
longis 64-bit (matches numpy’sint64). - On Windows,
longis only 32-bit—this will cause a type mismatch immediately withint64arrays.
For cross-platform safety, I’d recommend using int64_t (from <cstdint>) in your C++ code instead of raw long—it guarantees a 64-bit integer everywhere. But if you need to stick with long, adjust based on your OS.
Fix Your SWIG Interface File
You need to explicitly tell SWIG how to map numpy’s int64 arrays to your C++ type, and enable numpy support. Here’s a corrected example interface file:
%module my_array_module %{ // Include your C++ header here #include "array_processor.h" %} // Critical: Import numpy's SWIG support and initialize it %include "numpy.i" %init %{ import_array(); // Required to handle numpy arrays in SWIG %} // Map numpy int64 to C++ long (or int64_t for cross-platform) %numpy_typemaps(int64_t, NPY_INT64, long) // If your C++ function uses a pointer + length, apply these typemaps %apply long* INPLACE_ARRAY1 { long* arr } %apply int DIM1 { int arr_length } // Declare your C++ functions to SWIG %include "array_processor.h"
Example C++ Code
Let’s say your array_processor.h looks like this (adjust to your actual function):
#include <cstdint> // Using long for your original use case, or int64_t for cross-platform void multiply_array(long* arr, int arr_length) { for (int i = 0; i < arr_length; ++i) { arr[i] *= 2; // Simple demo operation } }
Python Test Code
Once you compile the SWIG module, call it like this to verify:
import numpy as np import my_array_module # Create an int64 numpy array test_arr = np.array([10, 20, 30, 40], dtype=np.int64) print("Before processing:", test_arr) # Call the C++ function my_array_module.multiply_array(test_arr) print("After processing:", test_arr)
Common Error Fixes
Windows Type Mismatch:
If you’re on Windows, swaplongin your C++ code and SWIG interface withlong long(since Windowslongis 32-bit). Update the typemap line to:%numpy_typemaps(int64_t, NPY_INT64, long long) %apply long long* INPLACE_ARRAY1 { long long* arr }Forgot numpy.i Setup:
Skipping%include "numpy.i"orimport_array()will cause SWIG to reject numpy arrays entirely—don’t skip these lines!Using
std::vector<long>Instead of Pointers:
If your C++ function uses a vector instead of a raw pointer, add SWIG’s std_vector support:%include "std_vector.i" %template(LongVector) std::vector<long>;You can then pass numpy arrays directly to functions accepting
std::vector<long>(SWIG handles the conversion).Compilation Issues:
When building your SWIG module (e.g., withsetup.py), make sure to include numpy’s header directory:from setuptools import setup, Extension import numpy as np my_module = Extension('_my_array_module', sources=['my_array_module_wrap.cxx', 'array_processor.cpp'], include_dirs=[np.get_include()]) setup(name='my_array_module', ext_modules=[my_module], py_modules=["my_array_module"])
内容的提问来源于stack exchange,提问作者ElenaZhebel

