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

Cython调用libc.bsearch获取排序数组索引返回异常值,求修正

修正Cython中使用libc.bsearch获取数组索引的错误

你在使用Cython调用libc的bsearch函数获取排序数组索引时,得到了错误的内存地址数值而非正确索引,问题出在指针处理逻辑和setup.py的依赖疏漏上,以下是具体修正方案:

错误原因分析

  • 指针转索引逻辑错误:bsearch返回的是指向找到元素的内存指针,你直接将指针强制转换为int类型,得到的是该指针的内存地址值(即你看到的610183044),而非数组中的元素索引。正确做法是通过指针偏移计算索引:用找到的指针减去数组起始指针,利用C语言指针相减自动除以元素大小的特性,直接得到索引值。
  • setup.py依赖缺失:代码中使用np.get_include()但未导入numpy,编译时会触发NameError。

修正后的代码

test_bsearch.pyx

cimport cython
from libc.stdlib cimport bsearch

cdef int comp_fun(const void *a, const void *b) nogil:
    cdef int a_v = (<int*>a)[0]
    cdef int b_v = (<int*>b)[0]

    if a_v < b_v:
        return -1
    elif a_v > b_v:
        return 1
    else:
        return 0


def bsearch_c(int[::1] t, int v):
    cdef int *p = <int*> bsearch(&v, &t[0], t.shape[0], sizeof(int), &comp_fun)
    
    if p != NULL:
        # 通过指针偏移计算元素索引
        return p - &t[0]
    else:
        return -1

setup.py

from distutils.core import setup
from Cython.Build import cythonize
import numpy as np  # 必须导入numpy才能调用np.get_include()

setup(
    ext_modules=cythonize([
        "test_bsearch.pyx"
    ],
        compiler_directives={'language_level': "3"}
    ),
    include_dirs=[
        np.get_include()
    ]
)

测试验证

重新执行编译命令python setup.py build_ext -i,运行测试代码即可得到正确结果:

>>> from test_bsearch import bsearch_c
>>> import numpy as np
>>> x = np.arange(20, dtype=np.int32)
>>> bsearch_c(x, 5)  # 返回5,结果正确

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 08:20:24