ctypes,python3.8:os错误:异常:访问冲突写入0x00000000

2024-06-07 23:11:42 发布

您现在位置:Python中文网/ 问答频道 /正文

我想通过python 3.8运行dll 我的dll部分中有一个函数:

void DLLAPI __stdcall GenerateReport (
    int             SeqContext,
    char*           szHost,
    char*           szDBName,
    char*           szUser,
    char*           szPasswd,
    const char*     szUut_Result_Id,
    char            szStylesheet[MAX_PATHNAME_LEN],
    char            szDestinationDir[MAX_DIRNAME_LEN],
    char            szPrefix[MAX_FILENAME_LEN],
    char            szFileName[MAX_PATHNAME_LEN],
    char            szPathName[MAX_PATHNAME_LEN],
    short*          psErrorOccurred,
    long*           plErrorCode,
    char            szErrorMessage[1024]
    );

对于python部分,我是这样做的:

def PrintReport():
    szNom_PV_Court = ''
    szErrormessage = ''
    sErrorok = 0
    lErrorcode = 0

    worker_ = cdll.LoadLibrary("D:\\users\\Worker.dll")

    if (worker_ == 0):
        print( " Could not open file DLL")

    worker_.GenerateReport( 0, "localhost" ,  "backend" , "user" , "test12", str( Uut_Result_Id ) , "D:\\users\\py\\ResourceFiles\\Gen.xsl" , "D:\\users\\py","" ,szNom_PV_Court , "D:\\users\\py" ,sErrorok ,lErrorcode ,szErrormessage )

当我执行代码时,我得到错误:OSError:exception:访问冲突写入0x0000000

我不明白这个错误,请帮忙


Tags: pyidlenresultusersmaxworkerdll
2条回答

您没有填充DLL的所有字符串,因此它们被初始化为零。您的dll正在尝试从地址0x0(零)读取数据,并因此受到操作系统的攻击。用正确的值填充所有必填字段

Python 3中的"localhost"等字符串是Unicode字符串,通过ctypes转换为wchar_t*。将b'localhost'用于转换为char*的字节字符串

另外,为函数定义.argtypes.restype,以便ctypes正确封送参数:

worker_.argtypes = c_int,c_char_p,c_char_p,c_char_p,c_char_p,c_char_p,c_char_p,c_char_p,c_char_p,c_char_p,c_char_p,POINTER(c_short),POINTER(c_long),c_char_p
worker_.restype = None

调用中也只有13个参数,但为函数定义了14个参数

short*long*使用以下命令创建可传递给调用的实例。现在您正在传递一个0作为默认值c_int,这可能是空指针异常的来源

sErrorok = c_short()
lErrorcode = c_long()

调用时使用byref(sErrorok)byref(lErrorcode)作为指针传递给调用

这里有一个完整的例子。我跳过了许多输入字符串,只显示一个以供参考:

test.c

#include <stdio.h>
#include <string.h>

#define DLLAPI __declspec(dllexport)

void DLLAPI __stdcall GenerateReport (
    int             SeqContext,
    char*           szHost,
    short*          psErrorOccurred,
    long*           plErrorCode,
    char            szErrorMessage[1024]
    )
{
    printf("SeqContext = %d szHost = %s\n",SeqContext,szHost);
    *psErrorOccurred = 5;
    *plErrorCode = 123;
    strcpy_s(szErrorMessage,1024,"error message");
}

test.py

from ctypes import *

szNom_PV_Court = ''
szErrormessage = ''
sErrorok = 0
lErrorcode = 0

dll = WinDLL('./test.dll')
dll.GenerateReport.argtypes = c_int,c_char_p,POINTER(c_short),POINTER(c_long),c_char_p
dll.GenerateReport.restype = None

err_occurred = c_short()
errcode = c_long()
errmsg = create_string_buffer(1024)

dll.GenerateReport(7,b'localhost',byref(err_occurred),byref(errcode),errmsg)
print(err_occurred.value,errcode.value,errmsg.value.decode())

输出:

SeqContext = 7 szHost = localhost
5 123 error message

相关问题 更多 >

    热门问题