Aravindhan <arvindh92...@yahoo.com> 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 <rep...@bugs.python.org>
<https://bugs.python.org/issue41021>
_______________________________________
_______________________________________________
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com

Reply via email to