Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. Qt for Python
  4. PySide6 with Python C API: EXC_BAD_ACCESS error when calling a method with inherited class from QRasterWindow

PySide6 with Python C API: EXC_BAD_ACCESS error when calling a method with inherited class from QRasterWindow

Scheduled Pinned Locked Moved Unsolved Qt for Python
qt for pythonpythonpyside
11 Posts 3 Posters 1.1k Views 2 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • B Offline
    B Offline
    Blady
    wrote on last edited by
    #1

    Environment:
    Python version: 3.9.6 (default, May 7 2023, 23:32:45)
    PySide6 version: 6.7.0

    When I create an instance of QRasterWindow, calling the metric method is ok:

    Py_Initialize();
    
        PyObject * GUI = PyImport_ImportModule("PySide6.QtGui");
        if(!GUI) {
            printf("\nCould not import PySide6.QtGui module.\n");
            return 0;
        }
    
        // QApplication
        PyObject* QGA = PyObject_GetAttrString(GUI, "QGuiApplication");
        PyObject * argsqa = PyTuple_New (1);
        PyObject * listqa = PyList_New (1);
        PyList_SetItem (listqa, 0, PyUnicode_FromString (""));
        PyTuple_SetItem (argsqa, 0, listqa);
        PyObject * res = PyObject_CallObject(QGA, argsqa);
    
        // QRasterWindow
        PyObject* QRW = PyObject_GetAttrString(GUI, "QRasterWindow");
        if(QRW) {
    
            // Create instance
            PyObject * args = PyTuple_New (0);
            PyObject * QRW_inst = PyObject_CallObject(QRW, args);
                 
            // Call metric
            PyObject * mm = PyObject_GetAttrString(QRW_inst, "metric");
    
            PyObject * uu = PyObject_GetAttrString(GUI, "QPaintDevice");
            PyObject * ww = PyObject_GetAttrString(uu, "PdmWidth");
    
            PyObject * argsm = PyTuple_New (1);
            PyTuple_SetItem (argsm, 0, ww);
            PyObject * res = PyObject_CallObject(mm, argsm);
    
            int val = PyLong_AsLong(res);
            printf("\nQRasterWindow.metric value is %d \n", val);
    
        } else {
            printf("\nCould not get QRW class.\n");
        }
    

    But if I create a class PCJ inherited from QRasterWindow then calling metric method gives segmentation fault EXC_BAD_ACCESS:

    // Create PCJ class inherited from QRasterWindow
        PyType_Slot slots[] = {
            { Py_tp_doc, "PGJ" },
            { Py_tp_base, QRW },
            { Py_tp_init, QRW_init },
            { 0 },
        };
        PyType_Spec spec = { "PCJ", 0, 0,
                              Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, slots };
        PyTypeObject *PCJ = (PyTypeObject *)PyType_FromSpec(&spec);
        printf("\nPCJ value is %d \n", PCJ);
    
        // Create PCJ instance
        PyObject * argsj = PyTuple_New (0);
        PyObject * PCJ_inst = PyObject_CallObject((PyObject *) PCJ, argsj);
        printf("\nPCJ_inst value is %d \n", PCJ_inst);
             
        // Call metric
        PyObject * mm = PyObject_GetAttrString(PCJ_inst, "metric");
        printf("\nmm value is %d \n", mm);
    
        PyObject * uu = PyObject_GetAttrString(GUI, "QPaintDevice");
        printf("\nuu value is %d \n", uu);
        PyObject * ww = PyObject_GetAttrString(uu, "PdmWidth");
        printf("\nww value is %d \n", ww);
    
        PyObject * argsm = PyTuple_New (1);
        PyTuple_SetItem (argsm, 0, ww);
        PyObject * resj = PyObject_CallObject(mm, argsm); // segmentation fault
        printf("\nresj value is %d \n", resj);
    
        int valj = PyLong_AsLong(resj);
        printf("\nPCJ.metric value is %d \n", valj);
    

    Output:

    QRasterWindow.metric value is 0 
    PCJ value is 436267760 
    In QRW_init 
    PCJ_inst value is 263891520 
    mm value is 263896816 
    uu value is 439183584 
    ww value is 263877728 
    zsh: segmentation fault
    

    What is wrong?

    1 Reply Last reply
    0
    • SGaistS Offline
      SGaistS Offline
      SGaist
      Lifetime Qt Champion
      wrote on last edited by SGaist
      #2

      Hi and welcome to devnet,

      Excuse my silly question but why go through the length of using PySide6 using Python C API ? Why not write your application directly in C++ ?

      Interested in AI ? www.idiap.ch
      Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

      1 Reply Last reply
      0
      • B Offline
        B Offline
        Blady
        wrote on last edited by
        #3

        Hi and thanks for your welcome.
        Good question, I'm trying to create Qt bindings for Ada language.
        Some attempts with C++ were failing due to some C++ subtleties.
        But Python provides C API which I can used easily with Ada.
        I provide some very first Qt bindings for Ada.
        But class inheritance is still in Python.
        I wanted to make them full Ada. I'm able to instantiate a class inherited from QRasterWindow (for instance) but a call to the method metric (for instance) provoques a seg fault.
        (for simplicity I post the code in C)

        V 1 Reply Last reply
        0
        • B Offline
          B Offline
          Blady
          wrote on last edited by
          #4

          With debugger, I get more information:

          thread #1, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=1, address=0x0)
            frame #0: libpyside6.abi3.6.7.dylib`PySide::SignalManager::retrieveMetaObject(_object*) + 80
            frame #1: QtGui.abi3.so`Sbk_QRasterWindow_Init(_object*, _object*, _object*) + 1073
            frame #2: example_06c`QRW_init(s=0x00000001038c16c0, a=0x000000010008b040, k=0x0000000000000000) at example_06c.c:5:25
          

          If it could help to find out what could be wrong or missing.

          1 Reply Last reply
          0
          • B Blady

            Hi and thanks for your welcome.
            Good question, I'm trying to create Qt bindings for Ada language.
            Some attempts with C++ were failing due to some C++ subtleties.
            But Python provides C API which I can used easily with Ada.
            I provide some very first Qt bindings for Ada.
            But class inheritance is still in Python.
            I wanted to make them full Ada. I'm able to instantiate a class inherited from QRasterWindow (for instance) but a call to the method metric (for instance) provoques a seg fault.
            (for simplicity I post the code in C)

            V Offline
            V Offline
            Ville Voutilainen
            wrote on last edited by
            #5

            @Blady said in PySide6 with Python C API: EXC_BAD_ACCESS error when calling a method with inherited class from QRasterWindow:

            Hi and thanks for your welcome.
            Good question, I'm trying to create Qt bindings for Ada language.
            Some attempts with C++ were failing due to some C++ subtleties.

            I'm interested in helping figure out and fix the C++ subtleties. It would seem rather reasonable to do such bridging between C++ and Ada without having to resort to a completely-interpreted language.

            B 1 Reply Last reply
            0
            • V Ville Voutilainen

              @Blady said in PySide6 with Python C API: EXC_BAD_ACCESS error when calling a method with inherited class from QRasterWindow:

              Hi and thanks for your welcome.
              Good question, I'm trying to create Qt bindings for Ada language.
              Some attempts with C++ were failing due to some C++ subtleties.

              I'm interested in helping figure out and fix the C++ subtleties. It would seem rather reasonable to do such bridging between C++ and Ada without having to resort to a completely-interpreted language.

              B Offline
              B Offline
              Blady
              wrote on last edited by
              #6

              @Ville-Voutilainen, thanks for you proposal!
              Unfortunately, C++ doesn't have a defined ABI.
              You have to deal with mangle names for the bindings.
              Mangle names are not stable from a code release to an other.
              You'll find several detail on the web, for instance:

              • https://stackoverflow.com/questions/611323/can-you-call-c-functions-from-ada
              • https://gcc.gnu.org/onlinedocs/gnat_ugn/Interfacing-with-C_002b_002b-at-the-Class-Level.html
              V 1 Reply Last reply
              0
              • B Offline
                B Offline
                Blady
                wrote on last edited by
                #7

                Update:
                Configuration still:

                • Python version: 3.9.6 (default, May 7 2023, 23:32:45)
                • PySide6 version: 6.7.0

                Results:

                • Inheritance with QRasterWindow and QWidget is failing.
                • Inheritance with QDate is succeeding.

                Further work:

                • try with a more recent Python version and a more recent PySide version.
                1 Reply Last reply
                0
                • B Blady

                  @Ville-Voutilainen, thanks for you proposal!
                  Unfortunately, C++ doesn't have a defined ABI.
                  You have to deal with mangle names for the bindings.
                  Mangle names are not stable from a code release to an other.
                  You'll find several detail on the web, for instance:

                  • https://stackoverflow.com/questions/611323/can-you-call-c-functions-from-ada
                  • https://gcc.gnu.org/onlinedocs/gnat_ugn/Interfacing-with-C_002b_002b-at-the-Class-Level.html
                  V Offline
                  V Offline
                  Ville Voutilainen
                  wrote last edited by Ville Voutilainen
                  #8

                  @Blady Well.. mangled names are stable unless you have an ABI break. If you keep your ABI as-is (and Qt does), GNAT should be able to call your C++ functions directly from Ada.

                  And what I would seriously want to look at here is generating the Ada bindings via a generator that uses C++26 reflection on the C++ side and writes out the right kind of Ada bindings. Including the parts where a mangled name is needed, like in the pragma imports.

                  B 1 Reply Last reply
                  2
                  • V Ville Voutilainen

                    @Blady Well.. mangled names are stable unless you have an ABI break. If you keep your ABI as-is (and Qt does), GNAT should be able to call your C++ functions directly from Ada.

                    And what I would seriously want to look at here is generating the Ada bindings via a generator that uses C++26 reflection on the C++ side and writes out the right kind of Ada bindings. Including the parts where a mangled name is needed, like in the pragma imports.

                    B Offline
                    B Offline
                    Blady
                    wrote last edited by
                    #9

                    @Ville-Voutilainen said in PySide6 with Python C API: EXC_BAD_ACCESS error when calling a method with inherited class from QRasterWindow:

                    And what I would seriously want to look at here is generating the Ada bindings via a generator that uses C++26 reflection on the C++ side and writes out the right kind of Ada bindings. Including the parts where a mangled name is needed, like in the pragma imports.

                    I don't know about C++26 reflection.
                    But GCC has a switch to generate binding from C++ header files, see GEM#60.
                    This generates all Ada code with the pragma Import and CPP_Constructor including mangle names.
                    I fear, if the original source code (i.e. Qt) changes then mangle names change that makes your Ada code not usable any more without an additional generation that is a pain.

                    V 1 Reply Last reply
                    0
                    • B Blady

                      @Ville-Voutilainen said in PySide6 with Python C API: EXC_BAD_ACCESS error when calling a method with inherited class from QRasterWindow:

                      And what I would seriously want to look at here is generating the Ada bindings via a generator that uses C++26 reflection on the C++ side and writes out the right kind of Ada bindings. Including the parts where a mangled name is needed, like in the pragma imports.

                      I don't know about C++26 reflection.
                      But GCC has a switch to generate binding from C++ header files, see GEM#60.
                      This generates all Ada code with the pragma Import and CPP_Constructor including mangle names.
                      I fear, if the original source code (i.e. Qt) changes then mangle names change that makes your Ada code not usable any more without an additional generation that is a pain.

                      V Offline
                      V Offline
                      Ville Voutilainen
                      wrote last edited by
                      #10

                      @Blady Well, the manglings change only if there's an ABI break. That doesn't happen.

                      B 1 Reply Last reply
                      0
                      • V Ville Voutilainen

                        @Blady Well, the manglings change only if there's an ABI break. That doesn't happen.

                        B Offline
                        B Offline
                        Blady
                        wrote last edited by
                        #11

                        @Ville-Voutilainen thanks for the information.
                        The order of declaration shall be the same in C++ and Ada.
                        If the order change on C++ side, you must regenerate all.

                        I guess this also implies to get the exact source code that have been used to build Qt library which has been released.
                        Generating Ada code from headers needs to set judiciously all defines that may differ from an OS to another.
                        I don't know how to cope with that.

                        Binding of multi-inheritance classes will be an issue too.

                        I would like to hope that it succeeds, but I haven't seen any new elements to that end.

                        1 Reply Last reply
                        0

                        • Login

                        • Login or register to search.
                        • First post
                          Last post
                        0
                        • Categories
                        • Recent
                        • Tags
                        • Popular
                        • Users
                        • Groups
                        • Search
                        • Get Qt Extensions
                        • Unsolved