i want to run a dll via python 3.8 i have a function in my dll part which is :
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]
);
For a python part i did like this :
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 )
when i execute my code i get error : OSError: exception: access violation writing 0x0000000
I'dont understand this error please help
Strings like "localhost"
in Python 3 are Unicode strings and translated to wchar_t*
by ctypes. Use b'localhost'
for byte strings that are translated to char*
.
Also, define .argtypes
and .restype
for your function to for ctypes to marshal your parameters properly:
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
You also only have 13 parameters in your call but 14 are defined for the function.
Use the following for the short*
and long*
to create instances that can be passed to the call. Right now you are passing a zero as the default c_int
which is probably the source of the null pointer exception.
sErrorok = c_short()
lErrorcode = c_long()
Call using byref(sErrorok)
and byref(lErrorcode)
to pass to the call as pointers.
Here's a complete example. I skipped the many input strings and just show one for reference:
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())
Output:
SeqContext = 7 szHost = localhost
5 123 error message
You hadn't filled all strings for DLL, so they was initialized to zero. Your dll is trying to read from address 0x0 (zero) and getting smacked by OS for this. Fill all required fields with proper values.
User contributions licensed under CC BY-SA 3.0