Python ctypes为堆栈分配更多内存
我有一个从python调用的c-dll。dll的输出非常大,我怀疑这会导致错误Python ctypes为堆栈分配更多内存,python,ctypes,Python,Ctypes,我有一个从python调用的c-dll。dll的输出非常大,我怀疑这会导致错误 OSError: exception: stack overflow 我很确定问题在于输出的大小(大约是4x25x720的两倍)。减小输出的大小(我不想这样做)可以消除错误 在C#中,我可以通过为调用线程分配更多内存来解决这个问题,即 thread = new Thread(() => calculate(ptr_in, ptr_out), 20000000); 是否可以对ctypes执行类似操作 这不是
OSError: exception: stack overflow
我很确定问题在于输出的大小(大约是4x25x720的两倍)。减小输出的大小(我不想这样做)可以消除错误
在C#中,我可以通过为调用线程分配更多内存来解决这个问题,即
thread = new Thread(() => calculate(ptr_in, ptr_out), 20000000);
是否可以对ctypes
执行类似操作
这不是张贴在这里的问题
编辑 考虑到这个问题,我认为问题不在于输出的大小,而在于实际dll本身所需的空间。即
c\u out internal\u out
在ctypes\u test.c中定义。不管怎样,问题还是一样
在C中,我定义了一个测试dll
dll\u ctypes\u test
ctypes\u testT.h
#pragma once
#define N_ELEMENTS 1000
#define N_ARRAYS 50
typedef struct
{
double var_0;
double var_1;
double var_2;
double var_3;
double var_4;
double var_5;
double var_6;
double var_7;
double var_8;
double var_9;
} element;
typedef struct
{
int n_elements;
element elements[N_ELEMENTS];
} arr;
typedef struct
{
int n_arrays;
arr arrays[N_ARRAYS];
} c_out;
ctypes\u test.c
#include "ctypes_testT.h"
__declspec(dllexport) void _stdcall dll_ctypes_test(double in, c_out *out)
{
c_out inner_out;
//Some caluclations on inner_out
//Wrap values of inner arr to out
}
还有Python代码
import ctypes
N_ELEMENTS = 1000
N_ARRAYS = 50
class element(ctypes.Structure):
_fields_ = [('var_0', ctypes.c_double),
('var_1', ctypes.c_double),
('var_2', ctypes.c_double),
('var_3', ctypes.c_double),
('var_4', ctypes.c_double),
('var_5', ctypes.c_double),
('var_6', ctypes.c_double),
('var_7', ctypes.c_double),
('var_8', ctypes.c_double),
('var_9', ctypes.c_double)]
class arr(ctypes.Structure):
_fields_ = [('n_elements', ctypes.c_int),
('elements', element * N_ELEMENTS)]
class c_out(ctypes.Structure):
_fields_ = [('n_arrays', ctypes.c_int),
('arrays', arr * N_ARRAYS)]
dll = ctypes.WinDLL(r'C:\repos\ctypes_test\x64\Debug\ctypes_test.dll')
dll.dll_ctypes_test.argtypes = [ctypes.c_double, ctypes.POINTER(c_out)]
dll.dll_ctypes_test.restype = None
dll.dll_ctypes_test(5, ctypes.byref(c_out()))
调用Python代码会产生
Traceback (most recent call last):
File "<ipython-input-15-7c8b287888d0>", line 1, in <module>
dll.dll_ctypes_test(5, c_out())
OSError: exception: access violation writing 0x00000062BA400000
回溯(最近一次呼叫最后一次):
文件“”,第1行,在
dll.dll\u ctypes\u test(5,c\u out())
OS错误:异常:访问冲突写入0x00000062BA400000
如果我将N_数组
从50
更改为,比如说,10
。错误消失。列表
我必须说,我无法使用“常规”Python或IPython重现行为(即使没有修复下面的错误)。也许dll\u ctypes\u测试实现的内容远不止这些
当前问题:
#pragma一次
#如果已定义(_WIN32)
#如果定义了DLL0\u导出
#定义DLL00_导出_API__declspec(dllexport)
#否则
#定义DLL00_导出_API__declspec(dllimport)
#恩迪夫
#否则
#定义DLL00\u导出\u API
#恩迪夫
#定义元素\u计数1000
#定义数组\u计数50
类型定义结构{
双变量0,变量1,变量2,变量3,变量4,
var5,var6,var7,var8,var9;
}元素;
类型定义结构{
整数大小;
元素数据[元素计数];
}阵列1d;
类型定义结构{
整数大小;
数组1d数据[数组计数];
}阵列2d;
#如果已定义(uuu cplusplus)
外部“C”{
#恩迪夫
DLL00\u导出\u API无效\u标准调用dll00Func00(双入式,阵列式*pOut);
#如果已定义(uuu cplusplus)
}
#恩迪夫
dll00.c:
#定义DLL0#u导出
#包括“dll0.h”
#包括
无效dll00Func00(双进,阵列2d*pOut){
如果(pOut==NULL){
printf(“从C传递的空数组\n”);
返回;
};
Array2D;
printf(“从C-外部数组大小:%d\n”,pOut->size);
}
代码00.py:
#/usr/bin/env python
导入系统
将ctypes导入为ct
元素计数=1000
数组计数=50
类元素(ct结构):
_字段=列表((((“var{0:d}).format(i),ct.c_double)表示范围(10)中的i)
类阵列1d(ct结构):
_字段=[
(“尺寸”,ct.c_int),
(“数据”,元素*元素计数),
]
类阵列2D(ct结构):
_字段=[
(“尺寸”,ct.c_int),
(“数据”,数组1d*数组计数),
]
DLL0_NAME=“./dll00.dll”
def主(*argv):
dll0=ct.windl(dll0\u名称)
dll00Func00=dll0.dll00Func00
dll00Func00.argtypes=[ct.c_double,ct.POINTER(Array2D)]
#dll00Func00.argtypes=[ct.c_double,Array2D]!!!!定义带指针的第二个参数会触发错误!!!
mat=Array2D()
材料尺寸=7
打印(“数组大小:{0:d}(0x{1:08X})”.format(ct.sizeof(mat),ct.sizeof(mat)))
dll00Func00(5,ct.byref(材料))
#dll00Func00(5,mat)
如果名称=“\uuuuu main\uuuuuuuu”:
打印(“Python{0:s}{1:d}位在{2:s}\n.format(“.join(sys.version.split(“\n”)中的项的item.strip()),如果sys.maxsize>0x100000000,则为64,否则为32,sys.platform))
main(*sys.argv[1:])
打印(“\n完成”)
输出:
e:\Work\Dev\StackOverflow\q060297181>sopr.bat
***设置较短的提示,以便粘贴到StackOverflow(或其他)页面时更适合***
[提示]>“c:\Install\pc032\Microsoft\VisualStudioCommunity\2017\VC\Auxiliary\Build\vcvarsall.bat”x64
**********************************************************************
**Visual Studio 2017开发者命令提示符v15.9.20
**版权所有(c)2017微软公司
**********************************************************************
[vcvarsall.bat]环境已初始化为:“x64”
[提示]>dir/b
代码00.py
dll0.h
dll00.c
[提示]>cl/nologo/MD/DDLL dll00.c/link/nologo/DLL/OUT:dll00.DLL
dll00.c
创建库dll00.lib和对象dll00.exp
[提示]>dir/b
代码00.py
dll0.h
dll00.c
dll00.dll
dll00.exp
dll00.lib
dll00.obj
[提示]>
[提示]>“e:\Work\Dev\VEnvs\py\u pc064\u 03.07.06\u test0\Scripts\python.exe”code00.py
win32上的Python 3.7.6(tags/v3.7.6:43364a7ae0,2019年12月19日,00:42:30)[MSC v.1916 64位(AMD64)]64位
阵列大小:4000408(0x003D0A98)
从C开始-外部阵列大小:7
完成。
调用函数或方法时(有一些异常,但这些异常与此无关),堆栈(一个特殊的内存区域)用于存储。正在存储的常见内容:
- 参数(和返回值),表示调用方和被调用方之间交换的数据
- 局部变量(在被调用方中),既不是静态的,也不是显式地分配给he