Aravindhan <[email protected]> added the comment:
Hi, Thanks for response @eryksun
Sorry that I did not mention it is compiled for x86 and the crash happens in
32bit python. Yes, the dll is declared with stdcall and built for x86 with
MSVC. It is tested with python 3.7.4 32bit which is successful and fails on
python 3.8.2 32bit. I did not look into on x64 though. Below is the source
code. I have also attached them as a zip.
>>> c/DummyCb.h
#pragma once
#include <Windows.h>
#include <iostream>
#define CALLBACK __stdcall
#define WINAPI __stdcall
#define EXFUNC(type) _declspec(dllexport) void WINAPI // export function
#define CBFUNC(type,func) typedef void (CALLBACK* func) // callback function
extern "C" CBFUNC(void, listen_cb)(int value, FILETIME ts );
extern "C" EXFUNC(void) subscribe_cb(listen_cb);
>>> c/DummyCb.cpp
#include "pch.h"
#include "DummyCb.h"
#include <stdio.h>
EXFUNC(void) subscribe_cb(listen_cb cb)
{
int i = 0;
while (true) {
FILETIME systime;
GetSystemTimeAsFileTime(&systime);
i++;
Sleep(1000);
cb(i, systime);
}
}
>>> c/CbClient.cpp
#include <iostream>
#include "DummyCb.h"
#include <stdio.h>
#include <Windows.h>
void __stdcall lis(int a, FILETIME ts) {
printf("calling back %d, %d, %d \n", a,ts.dwHighDateTime,
ts.dwLowDateTime);
}
int main()
{
subscribe_cb(&lis);
}
>>> CbClient.py
from ctypes import *
from time import sleep
class FT(Structure):
_fields_ = [("dwLowDateTime", c_ulong, 32),
("dwHighDateTime", c_ulong, 32)]
@WINFUNCTYPE(c_void_p, c_int, FT)
def cb(val, ft):
print(f"callback {val} {ft.dwLowDateTime} {ft.dwHighDateTime}")
lib = WinDLL(r"c/DummyCb.dll")
lib.subscribe_cb(cb)
while 1:
sleep(5)
>>> Traceback on python
lib.subscribe_cb(cb)
OSError: exception: access violation writing 0xCA35789B
>>> Native Debug traceback
Run-Time Check Failure #0 - The value of ESP was not properly saved across a
function call. This is usually a result of calling a function declared with one
calling convention with a function pointer declared with a different calling
convention.
>>> Further analysis
change the callback declaration to a pointer of structure and it has same crash
on python 3.7 32 bit.
@WINFUNCTYPE(c_void_p, c_int, POINTER(FT))
def cb(val, ft):
print(f"callback {val} {ft.contents}")
Which makes me correlate is it something to do with vector calling on python
3.8 which makes callabck as *cb (a pointer) instead of a plain object call
(just a thought, did not investigate change logs). Though its interesting to
note that it did not fail on x64 with cdecl calling convention. That explains
why our larger code base din't crash on Linux x86 linked as a .SO .
cheers.
----------
Added file: https://bugs.python.org/file49253/callback.zip
_______________________________________
Python tracker <[email protected]>
<https://bugs.python.org/issue41021>
_______________________________________
_______________________________________________
Python-bugs-list mailing list
Unsubscribe:
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com