WindowsError:异常:使用从 C++ 到 Python 的 ctypes 创建 DLL 时出现访问冲突或 Windows 错误 193
Posted
技术标签:
【中文标题】WindowsError:异常:使用从 C++ 到 Python 的 ctypes 创建 DLL 时出现访问冲突或 Windows 错误 193【英文标题】:WindowsError: exception: access violation or Windows Error 193 when creating a DLL using ctypes from C++ to Python 【发布时间】:2018-05-03 21:03:56 【问题描述】:我从 PyCharm 收到此错误: WindowsError:异常:访问冲突读取 0x000000504D414C43
它只出现在 Pycharm 中。当我从 Windows Powershell 运行 python 脚本时,它显示 WindowsError: [Error 193] %1 is not a valid Win32 application。我检查了调试器并且正在传递一个值,但它有时会出错给我空指针。起初,我以为我在用完数组,但即使我只返回 7(如您在底部看到的那样)并注释掉所有代码,它仍然会按照描述进行。
问题:
1) 你有什么解决办法吗?
2) 我是否正确设置了 DLL?
3)有什么建议吗?
非常感谢您的帮助。
这是我的 C++ 代码:
#include <iostream>
#include <string>
#include <array>
#include "external_lists.h"
extern creation_object A1[];
extern creation_object A2[];
extern int A1size;
extern int A2size;
#define DLLEXPORT extern "C" __declspec(dllexport)
DLLEXPORT int get_creation_data(std::string needed_name)
int A1_size = ( A1size/ sizeof(A1[0])) ;
int A2_size = ( A2size / sizeof(A2[0])) ;
for (int i = 0; i < A1_size; i++)
if (A1[i].name == needed_name)
return A1[i].value->section;
return 7;
这是我的 python 包装器:
import os, sys, re
from ctypes import *
def get_creation_values(value_name):
trimdll = CDLL('C:\\Documents\\creation.dll')
return valuedll.get_creation_data(value_name)
if __name__ == "__main__":
val = get_value('CLAMP')
print(val)
总体目标:
我有一个无法修改但需要在 C++ 中访问的大文件。 C++ 文件中有很大的列表,我需要遍历这些列表并将值返回给 python 脚本。
【问题讨论】:
Ctypes 只理解 C 类型。您不能在函数签名中使用 std::string。 【参考方案1】:ctypes
只理解 C 类型。您可以将字节字符串作为const char*
传递,并在需要时将其分配给std::string
。这是一个完整的工作示例:
C++ 代码 (test.cpp)
#include <string>
#define DLLEXPORT extern "C" __declspec(dllexport)
DLLEXPORT int get_creation_data(const char* name)
std::string needed_name(name);
if(needed_name == "Armaja")
return 1;
return 0;
Python 代码
from ctypes import *
def get_creation_values(value_name):
trimdll = CDLL('test')
trimdll.get_creation_data.argtypes = [c_char_p]
trimdll.get_creation_data.restype = c_int
return trimdll.get_creation_data(value_name)
if __name__ == "__main__":
val = get_creation_values(b'Armaja')
print(val)
输出:
1
注意如何指定 DLL 函数的参数类型和返回值。这有助于捕获错误。例如,尝试传递 Unicode 字符串 'Armaja'
而不是字节字符串 b'Armaja'
(Python 3 语法):
Traceback (most recent call last):
File "C:\test.py", line 10, in <module>
val = get_creation_values('Armaja')
File "C:\test.py", line 7, in get_creation_values
return trimdll.get_creation_data(value_name)
ctypes.ArgumentError: argument 1: <class 'TypeError'>: wrong type
【讨论】:
您好,谢谢您,我不再看到该错误,并且我现在明白,当涉及到 DLL 时,参数需要 C 类型。您能否解释一下这些行:' trimdll.get_creation_data.argtypes = [c_char_p] trimdll.get_creation_data.restype = c_int ' 另外,你知道有没有办法返回一个对象?由于 C 类型似乎只知道原始类型,这可能吗?再次感谢您。 ctypes documentation 记录 argtypes 和 restype。第一个是函数的参数类型列表,第二个是返回类型。ctypes
只处理 C 类型,所以不能返回对象。可以为 C++ 对象创建 C 接口。 SWIG 之类的工具可以自动执行此操作。以上是关于WindowsError:异常:使用从 C++ 到 Python 的 ctypes 创建 DLL 时出现访问冲突或 Windows 错误 193的主要内容,如果未能解决你的问题,请参考以下文章
pytesseract,WindowsError: [错误2] 系统找不到指定的文件
WindowsError:[错误 126] 找不到指定的模块