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
相关产品推荐
相关产品推荐

