Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Special Interest Groups
  3. C++ Gurus
  4. Incompatible pointer type when referencing the method.

Incompatible pointer type when referencing the method.

Scheduled Pinned Locked Moved Solved C++ Gurus
pdfiumreference error
14 Posts 4 Posters 2.6k Views
  • 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.
  • artwawA Offline
    artwawA Offline
    artwaw
    wrote on last edited by artwaw
    #1

    Good morning,
    my lack of c++ knowledge struck me hard today.

    Context:
    I need to write a tool for certain manipulations of pdf documents. While to load and display them is no problem across the platforms, I used Poppler for that multiple times, this time I also need to be able to edit structure, think remove/add pages, and then write down. So I did my research and head towards PDFium.
    PDFium is not really well documented but I sufficiently enough so I got it working to some extent. The problem I have is in one particular place when writing down modified file.

    To write down the file, there is a method:

    // Function: FPDF_SaveAsCopy
    //          Saves the copy of specified document in custom way.
    // Parameters:
    //          document        -   Handle to document, as returned by
    //                              FPDF_LoadDocument() or FPDF_CreateNewDocument().
    //          pFileWrite      -   A pointer to a custom file write structure.
    //          flags           -   The creating flags.
    // Return value:
    //          TRUE for succeed, FALSE for failed.
    //
    FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV FPDF_SaveAsCopy(FPDF_DOCUMENT document,
                                                        FPDF_FILEWRITE* pFileWrite,
                                                        FPDF_DWORD flags);
    

    and associated structure with a callback method for writing down a block of data:

    // Structure for custom file write
    typedef struct FPDF_FILEWRITE_ {
      //
      // Version number of the interface. Currently must be 1.
      //
      int version;
    
      // Method: WriteBlock
      //          Output a block of data in your custom way.
      // Interface Version:
      //          1
      // Implementation Required:
      //          Yes
      // Comments:
      //          Called by function FPDF_SaveDocument
      // Parameters:
      //          pThis       -   Pointer to the structure itself
      //          pData       -   Pointer to a buffer to output
      //          size        -   The size of the buffer.
      // Return value:
      //          Should be non-zero if successful, zero for error.
      int (*WriteBlock)(struct FPDF_FILEWRITE_* pThis,
                        const void* pData,
                        unsigned long size);
    

    The problem:
    I have a member variable of the QDataStream called writerStream in the class (named PdfWizard), I also defined the method to be referenced as private: int blockWriter(FPDF_FILEWRITE* pThis, const void* pData, unsigned long size);
    This is implemented:

    int PdfWizard::blockWriter(FPDF_FILEWRITE* pThis, const void* pData, unsigned long size) {
        Q_UNUSED(pThis)
        return writerStream.writeRawData(static_cast<const char*>(pData), size);
    }
    

    The actual writing part, after opening the stream for writing, is:

        FPDF_FILEWRITE writer;
        writer.version = 1; 
        writer.WriteBlock = &PdfWizard::blockWriter; //here is my error
        bool result = FPDF_SaveAsCopy(document, &writer,FPDF_INCREMENTAL);
    

    On the line 3 of the above code block Qt complains:
    PdfWizard.cpp:357:25: error: assigning to 'int (*)(struct FPDF_FILEWRITE_ *, const void *, unsigned long)' from incompatible type 'int (PdfWizard::*)(FPDF_FILEWRITE *, const void *, unsigned long)'

    What is the right way of making it work? This is the very first time I encountered the need to reference a method like this and I am lost.

    Many thanks in advance,
    Artur

    For more information please re-read.

    Kind Regards,
    Artur

    jsulmJ 1 Reply Last reply
    0
    • artwawA artwaw

      @jsulm but how?
      Sure, I can move that callback outside the class. That also means I'd need to somehow move the QDataStream outside... I am not sure if I know how to safely and correctly design that.
      PdfWizard is of QMainWindow, so everything is in it.

      jsulmJ Offline
      jsulmJ Offline
      jsulm
      Lifetime Qt Champion
      wrote on last edited by
      #9

      @artwaw said in Incompatible pointer type when referencing the method.:

      but how?

      Well, you need to get access to the instance. One way is to make the class a singleton.

      https://forum.qt.io/topic/113070/qt-code-of-conduct

      artwawA 1 Reply Last reply
      1
      • artwawA artwaw

        Good morning,
        my lack of c++ knowledge struck me hard today.

        Context:
        I need to write a tool for certain manipulations of pdf documents. While to load and display them is no problem across the platforms, I used Poppler for that multiple times, this time I also need to be able to edit structure, think remove/add pages, and then write down. So I did my research and head towards PDFium.
        PDFium is not really well documented but I sufficiently enough so I got it working to some extent. The problem I have is in one particular place when writing down modified file.

        To write down the file, there is a method:

        // Function: FPDF_SaveAsCopy
        //          Saves the copy of specified document in custom way.
        // Parameters:
        //          document        -   Handle to document, as returned by
        //                              FPDF_LoadDocument() or FPDF_CreateNewDocument().
        //          pFileWrite      -   A pointer to a custom file write structure.
        //          flags           -   The creating flags.
        // Return value:
        //          TRUE for succeed, FALSE for failed.
        //
        FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV FPDF_SaveAsCopy(FPDF_DOCUMENT document,
                                                            FPDF_FILEWRITE* pFileWrite,
                                                            FPDF_DWORD flags);
        

        and associated structure with a callback method for writing down a block of data:

        // Structure for custom file write
        typedef struct FPDF_FILEWRITE_ {
          //
          // Version number of the interface. Currently must be 1.
          //
          int version;
        
          // Method: WriteBlock
          //          Output a block of data in your custom way.
          // Interface Version:
          //          1
          // Implementation Required:
          //          Yes
          // Comments:
          //          Called by function FPDF_SaveDocument
          // Parameters:
          //          pThis       -   Pointer to the structure itself
          //          pData       -   Pointer to a buffer to output
          //          size        -   The size of the buffer.
          // Return value:
          //          Should be non-zero if successful, zero for error.
          int (*WriteBlock)(struct FPDF_FILEWRITE_* pThis,
                            const void* pData,
                            unsigned long size);
        

        The problem:
        I have a member variable of the QDataStream called writerStream in the class (named PdfWizard), I also defined the method to be referenced as private: int blockWriter(FPDF_FILEWRITE* pThis, const void* pData, unsigned long size);
        This is implemented:

        int PdfWizard::blockWriter(FPDF_FILEWRITE* pThis, const void* pData, unsigned long size) {
            Q_UNUSED(pThis)
            return writerStream.writeRawData(static_cast<const char*>(pData), size);
        }
        

        The actual writing part, after opening the stream for writing, is:

            FPDF_FILEWRITE writer;
            writer.version = 1; 
            writer.WriteBlock = &PdfWizard::blockWriter; //here is my error
            bool result = FPDF_SaveAsCopy(document, &writer,FPDF_INCREMENTAL);
        

        On the line 3 of the above code block Qt complains:
        PdfWizard.cpp:357:25: error: assigning to 'int (*)(struct FPDF_FILEWRITE_ *, const void *, unsigned long)' from incompatible type 'int (PdfWizard::*)(FPDF_FILEWRITE *, const void *, unsigned long)'

        What is the right way of making it work? This is the very first time I encountered the need to reference a method like this and I am lost.

        Many thanks in advance,
        Artur

        jsulmJ Offline
        jsulmJ Offline
        jsulm
        Lifetime Qt Champion
        wrote on last edited by
        #2

        @artwaw You are trying to assign a pointer to a method to a function pointer. This can't work.
        Use a function instead and in that function call your class.

        https://forum.qt.io/topic/113070/qt-code-of-conduct

        artwawA 1 Reply Last reply
        0
        • jsulmJ jsulm

          @artwaw You are trying to assign a pointer to a method to a function pointer. This can't work.
          Use a function instead and in that function call your class.

          artwawA Offline
          artwawA Offline
          artwaw
          wrote on last edited by
          #3

          @jsulm but how?
          Sure, I can move that callback outside the class. That also means I'd need to somehow move the QDataStream outside... I am not sure if I know how to safely and correctly design that.
          PdfWizard is of QMainWindow, so everything is in it.

          For more information please re-read.

          Kind Regards,
          Artur

          J.HilkJ jsulmJ 2 Replies Last reply
          0
          • artwawA artwaw

            @jsulm but how?
            Sure, I can move that callback outside the class. That also means I'd need to somehow move the QDataStream outside... I am not sure if I know how to safely and correctly design that.
            PdfWizard is of QMainWindow, so everything is in it.

            J.HilkJ Offline
            J.HilkJ Offline
            J.Hilk
            Moderators
            wrote on last edited by
            #4

            @artwaw

            I think you could simply use a lambda stored in an auto and capture a reference to your QDataStream and/or class instance in general.

            not the cleanest solution, but should work.


            Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


            Q: What's that?
            A: It's blue light.
            Q: What does it do?
            A: It turns blue.

            artwawA 1 Reply Last reply
            1
            • J.HilkJ J.Hilk

              @artwaw

              I think you could simply use a lambda stored in an auto and capture a reference to your QDataStream and/or class instance in general.

              not the cleanest solution, but should work.

              artwawA Offline
              artwawA Offline
              artwaw
              wrote on last edited by
              #5

              @J-Hilk Thank you but I don't know how to do that. I use lambdas with connect when needed, but my c++ skill is not enough.

              I could get away with making QDataStream a public member of QMainWindow but I feel dirty just thinking of it.

              For more information please re-read.

              Kind Regards,
              Artur

              J.HilkJ 1 Reply Last reply
              0
              • artwawA artwaw

                @J-Hilk Thank you but I don't know how to do that. I use lambdas with connect when needed, but my c++ skill is not enough.

                I could get away with making QDataStream a public member of QMainWindow but I feel dirty just thinking of it.

                J.HilkJ Offline
                J.HilkJ Offline
                J.Hilk
                Moderators
                wrote on last edited by
                #6

                @artwaw said in Incompatible pointer type when referencing the method.:

                Thank you but I don't know how to do that. I use lambdas with connect when needed, but my c++ skill is not enough.

                this is untested:

                FPDF_FILEWRITE writer;
                    writer.version = 1; 
                    auto myFunction = [this](FPDF_FILEWRITE* pThis, const void* pData, unsigned long size)->int {
                        Q_UNUSED(pThis)
                        return writerStream.writeRawData(static_cast<const char*>(pData), size);
                }
                    writer.WriteBlock = &myFunction;
                    bool result = FPDF_SaveAsCopy(document, &writer,FPDF_INCREMENTAL);
                

                Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


                Q: What's that?
                A: It's blue light.
                Q: What does it do?
                A: It turns blue.

                artwawA 2 Replies Last reply
                1
                • J.HilkJ J.Hilk

                  @artwaw said in Incompatible pointer type when referencing the method.:

                  Thank you but I don't know how to do that. I use lambdas with connect when needed, but my c++ skill is not enough.

                  this is untested:

                  FPDF_FILEWRITE writer;
                      writer.version = 1; 
                      auto myFunction = [this](FPDF_FILEWRITE* pThis, const void* pData, unsigned long size)->int {
                          Q_UNUSED(pThis)
                          return writerStream.writeRawData(static_cast<const char*>(pData), size);
                  }
                      writer.WriteBlock = &myFunction;
                      bool result = FPDF_SaveAsCopy(document, &writer,FPDF_INCREMENTAL);
                  
                  artwawA Offline
                  artwawA Offline
                  artwaw
                  wrote on last edited by
                  #7

                  @J-Hilk Thank you, will test.

                  For more information please re-read.

                  Kind Regards,
                  Artur

                  1 Reply Last reply
                  0
                  • J.HilkJ J.Hilk

                    @artwaw said in Incompatible pointer type when referencing the method.:

                    Thank you but I don't know how to do that. I use lambdas with connect when needed, but my c++ skill is not enough.

                    this is untested:

                    FPDF_FILEWRITE writer;
                        writer.version = 1; 
                        auto myFunction = [this](FPDF_FILEWRITE* pThis, const void* pData, unsigned long size)->int {
                            Q_UNUSED(pThis)
                            return writerStream.writeRawData(static_cast<const char*>(pData), size);
                    }
                        writer.WriteBlock = &myFunction;
                        bool result = FPDF_SaveAsCopy(document, &writer,FPDF_INCREMENTAL);
                    
                    artwawA Offline
                    artwawA Offline
                    artwaw
                    wrote on last edited by
                    #8

                    @J-Hilk
                    PdfWizard.cpp:358:25: error: incompatible pointer types assigning to 'int (*)(struct FPDF_FILEWRITE_ *, const void *, unsigned long)' from '(lambda at PdfWizard.cpp:350:24) *'

                    For more information please re-read.

                    Kind Regards,
                    Artur

                    J.HilkJ 1 Reply Last reply
                    0
                    • artwawA artwaw

                      @jsulm but how?
                      Sure, I can move that callback outside the class. That also means I'd need to somehow move the QDataStream outside... I am not sure if I know how to safely and correctly design that.
                      PdfWizard is of QMainWindow, so everything is in it.

                      jsulmJ Offline
                      jsulmJ Offline
                      jsulm
                      Lifetime Qt Champion
                      wrote on last edited by
                      #9

                      @artwaw said in Incompatible pointer type when referencing the method.:

                      but how?

                      Well, you need to get access to the instance. One way is to make the class a singleton.

                      https://forum.qt.io/topic/113070/qt-code-of-conduct

                      artwawA 1 Reply Last reply
                      1
                      • jsulmJ jsulm

                        @artwaw said in Incompatible pointer type when referencing the method.:

                        but how?

                        Well, you need to get access to the instance. One way is to make the class a singleton.

                        artwawA Offline
                        artwawA Offline
                        artwaw
                        wrote on last edited by
                        #10

                        @jsulm said in Incompatible pointer type when referencing the method.:

                        make the class a singleton

                        I went here https://www.oreilly.com/library/view/c-cookbook/0596007612/ch08s10.html

                        This is doable, I think, but at this point I am coming to the conclusion that it would be better to redesign my approach by wrapping all interactions with PDFium into a separate class and only expose methods that do stuff I need.

                        There is so much I don't know how to do yet...

                        For more information please re-read.

                        Kind Regards,
                        Artur

                        1 Reply Last reply
                        0
                        • artwawA artwaw

                          @J-Hilk
                          PdfWizard.cpp:358:25: error: incompatible pointer types assigning to 'int (*)(struct FPDF_FILEWRITE_ *, const void *, unsigned long)' from '(lambda at PdfWizard.cpp:350:24) *'

                          J.HilkJ Offline
                          J.HilkJ Offline
                          J.Hilk
                          Moderators
                          wrote on last edited by
                          #11

                          @artwaw oops, my bad, a lambda can only be converted to a function pointer if it does not capture

                          The closure type for a lambda-expression with no lambda-capture has a public non-virtual non-explicit const conversion function to pointer to function having the same parameter and return types as the closure type’s function call operator. The value returned by this conversion function shall be the address of a function that, when invoked, has the same effect as invoking the closure type’s function call operator.

                          Reference link


                          Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


                          Q: What's that?
                          A: It's blue light.
                          Q: What does it do?
                          A: It turns blue.

                          1 Reply Last reply
                          1
                          • artwawA Offline
                            artwawA Offline
                            artwaw
                            wrote on last edited by
                            #12

                            I managed to construct a singleton class to handle the I/O and so it works. Thank you all for the input, it is always great to learn from you!

                            For more information please re-read.

                            Kind Regards,
                            Artur

                            1 Reply Last reply
                            1
                            • M Offline
                              M Offline
                              mpergand
                              wrote on last edited by mpergand
                              #13

                              I know nothing about Poppler but for defining a C callback method in C++, this method need to be static.
                              See this post

                              artwawA 1 Reply Last reply
                              0
                              • M mpergand

                                I know nothing about Poppler but for defining a C callback method in C++, this method need to be static.
                                See this post

                                artwawA Offline
                                artwawA Offline
                                artwaw
                                wrote on last edited by
                                #14

                                @mpergand thank you but:

                                • I stated previously that I work with PDFium this time, as Poppler doesn't offer edits;
                                • I managed to work around without using static method: maybe not the nicest solution around but works.

                                At any rate I made a note of your comment in case I need to revisit this godawful file format known as PDF in the future.

                                For more information please re-read.

                                Kind Regards,
                                Artur

                                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