Cython链接共享库报错?Cuba库Cuhre例程调用问题
Got it, let's work through getting your custom libcuhre.so hooked up with Cython—since you ran into issues linking the static Cuba library directly, this shared library approach should smooth things out.
First, let's confirm your shared library is properly compiled (this is the foundation). You need to build cuhre.c with position-independent code (required for shared libraries) and link against the Cuba library to resolve the underlying Cuhre calls. Use a command like this:
gcc -fPIC -shared -o libcuhre.so cuhre.c -I/path/to/cuba/include -L/path/to/cuba/lib -lcuba
- Replace
/path/to/cuba/includeand/path/to/cuba/libwith the actual paths to your Cuba library's headers and binaries. - The
-lcubaflag tells the linker to pull in the Cuba library (dynamic is safer here, but static works if you have the right flags).
Step 1: Write the Cython Wrapper
Create a file named cuhre_wrapper.pyx to bridge your C shared library with Python. We'll declare the C types/functions from cuhre.h and create a wrapper that lets Python functions act as the integrand:
# Declare the C types and functions from your cuhre.h cdef extern from "cuhre.h": # Match the integrand_t typedef from Cuba's headers ctypedef void (*integrand_t)(int ndim, const double xx[], int ncomp, double ff[], void *userdata) double tryCuhre(integrand_t t, void *ud) # Intermediate Cython function to wrap Python integrands cdef void py_integrand(int ndim, const double xx[], int ncomp, double ff[], void *userdata): # Convert the C array xx to a Python list for easier handling cdef list x_vals = [xx[i] for i in range(ndim)] # Retrieve the Python integrand function from userdata cdef object py_func = <object>userdata # Evaluate the Python function and store the result ff[0] = py_func(x_vals) # Expose a Python-callable function to run the integration def integrate(py_integrand_func): return tryCuhre(py_integrand, <void *>py_integrand_func)
Step 2: Configure the Setup Script
Create a setup.py to compile the Cython module and link against your libcuhre.so:
from setuptools import setup, Extension from Cython.Build import cythonize # Define the Cython extension ext = Extension( name="cuhre_wrapper", sources=["cuhre_wrapper.pyx"], include_dirs=["."], # Path to your cuhre.h libraries=["cuhre"], # Link against libcuhre.so library_dirs=["."], # Path to your libcuhre.so runtime_library_dirs=["."] # Ensure the shared library is found at runtime ) setup( name="Cuhre Integration Wrapper", ext_modules=cythonize(ext) )
Step 3: Compile and Test
- Compile the Cython module:
python setup.py build_ext --inplace
- Make sure your system can find
libcuhre.soat runtime. Either move it to a standard library path (like/usr/local/lib) or set theLD_LIBRARY_PATHenvironment variable:
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:.
- Test with a simple Python script:
import cuhre_wrapper def my_2d_integrand(x): # Example: integrate x0 + x1 over [0,1]x[0,1] (expected result: 1.0) return x[0] + x[1] result = cuhre_wrapper.integrate(my_2d_integrand) print(f"Integral Result: {result}")
Troubleshooting Tips
- Undefined reference errors: Double-check that
libcuhre.sowas compiled with-lcubaand that the Cuba library path is correct. - Runtime library not found: Verify
LD_LIBRARY_PATHincludes the directory withlibcuhre.so, or userpathflags in theExtensiondefinition to embed the path. - Integrand type mismatches: Ensure your
cuhre.hcorrectly includescuba.hsointegrand_tis properly defined—this is critical for matching the function signature expected bytryCuhre.
内容的提问来源于stack exchange,提问作者paulinho

