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

Python调用C编写的main函数触发内存访问违例问题求助

问题分析与修复方案

核心问题:C与Python数组传递的内存布局不兼容

触发OSError: exception: access violation reading 0x0000000000000000的本质原因是:C函数期望的int**(指针数组,每个元素指向独立的一维数组),和Python传递的numpy二维数组内存结构完全不匹配。numpy二维数组是连续的内存块,而非指针数组,导致C中访问data[k][j]时读取到无效地址(比如0),引发访问违例。


具体修复步骤

1. 重构C函数的参数与逻辑

  • 不要用main作为函数名(这是C程序的入口函数,动态库中使用会引发混淆),改为hough_transform。
  • 将参数从int** data改为连续内存的一维指针,同时显式传入数组的行数、列数(C无法自动获取numpy数组的尺寸):
#include <math.h>
#include <float.h> // 用于处理无穷大值

float hough_transform(int* data, int rows, int cols) {
    float pi = 3.14159265;
    int max_distance = 182;
    int thetas = 181;
    int accumulator[182][181] = {0};
    int i, j, k, r, m, theta1 = 0, radius1 = 0; // 初始化变量,避免未定义行为
    int current_max = 0;
    double angle;
    float slope1 = 0.0f;

    // 遍历数组:用data[i * cols + j]访问连续内存中的二维元素
    for (i = 0; i < rows; i++) {
        k = 127 - i;
        for (j = 0; j < cols; j++) {
            if (data[i * cols + j] != 0) {
                for (m = 0; m < thetas; m++) {
                    angle = -(pi/2) + (m * pi/2) / 90.0;
                    double r_double = fabs((double)j * cos(angle) + (double)k * sin(angle));
                    r = (int)r_double;
                    // 限制r的范围,避免accumulator数组越界
                    if (r >= max_distance) r = max_distance - 1;
                    accumulator[r][m]++;
                }
            }
        }
    }

    // 遍历累加器找最大值
    for (i = 0; i < max_distance; i++) {
        for (j = 0; j < thetas; j++) {
            if (accumulator[i][j] > current_max) {
                current_max = accumulator[i][j];
                radius1 = i;
                theta1 = j - 90;
            }
        }
    }

    // 计算斜率,处理tan(pi/2)无穷大的情况
    angle = (double)theta1 * pi / 180.0;
    double tan_val = tan(angle + pi/2);
    slope1 = (isinf(tan_val)) ? FLT_MAX : (float)tan_val;
    return slope1;
}

2. 调整Python端的函数签名与调用逻辑

  • 修正argtypes,匹配C函数的参数类型,同时确保numpy数组是连续内存布局:
import ctypes
import numpy as np
from numpy.ctypeslib import ndpointer

# 加载动态库
fun = ctypes.CDLL("C:/Coding_Projects/Hough_Proj/C/HoughTransform.dll")
# 声明函数签名:返回float,参数为int指针、行数、列数
fun.hough_transform.argtypes = [ndpointer(dtype=np.int32, ndim=1), ctypes.c_int, ctypes.c_int]
fun.hough_transform.restype = ctypes.c_float

i = 0
while i < len(slopes):
    j = 0
    currentslopes = slopes[i]
    currenttest = tests[i]
    while j < 47:
        currentset = np.array(currenttest[j], dtype=np.int32)
        # 确保数组是连续内存布局,避免传递时出错
        currentset_contig = np.ascontiguousarray(currentset)
        rows, cols = currentset_contig.shape
        # 调用C函数,传入展平后的数组、行数、列数
        result = fun.hough_transform(currentset_contig, rows, cols)
        currentslopes.append(result)
        j += 1
    i += 1

额外注意事项

  • 编译C代码时必须链接数学库(比如GCC编译加-lm参数),否则会出现cos/sin/tan未定义的错误。
  • 确认currenttest[j]是二维数组,若为一维数组会导致C函数逻辑错误。
  • 处理tan(pi/2)的无穷大情况,避免返回无效浮点值。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.22 05:37:37