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.
  • A Offline
    A Offline
    artwaw
    wrote on 11 Nov 2021, 10:35 last edited by artwaw 11 Nov 2021, 10:35
    #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

    J 1 Reply Last reply 11 Nov 2021, 10:40
    0
    • A artwaw
      11 Nov 2021, 10:45

      @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 Online
      J Online
      jsulm
      Lifetime Qt Champion
      wrote on 11 Nov 2021, 11:36 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

      A 1 Reply Last reply 11 Nov 2021, 11:42
      1
      • A artwaw
        11 Nov 2021, 10:35

        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

        J Online
        J Online
        jsulm
        Lifetime Qt Champion
        wrote on 11 Nov 2021, 10:40 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

        A 1 Reply Last reply 11 Nov 2021, 10:45
        0
        • J jsulm
          11 Nov 2021, 10:40

          @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.

          A Offline
          A Offline
          artwaw
          wrote on 11 Nov 2021, 10:45 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 J 2 Replies Last reply 11 Nov 2021, 10:51
          0
          • A artwaw
            11 Nov 2021, 10:45

            @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 Online
            J Online
            J.Hilk
            Moderators
            wrote on 11 Nov 2021, 10:51 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.

            A 1 Reply Last reply 11 Nov 2021, 11:14
            1
            • J J.Hilk
              11 Nov 2021, 10:51

              @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.

              A Offline
              A Offline
              artwaw
              wrote on 11 Nov 2021, 11:14 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 1 Reply Last reply 11 Nov 2021, 11:20
              0
              • A artwaw
                11 Nov 2021, 11:14

                @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 Online
                J Online
                J.Hilk
                Moderators
                wrote on 11 Nov 2021, 11:20 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.

                A 2 Replies Last reply 11 Nov 2021, 11:22
                1
                • J J.Hilk
                  11 Nov 2021, 11:20

                  @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);
                  
                  A Offline
                  A Offline
                  artwaw
                  wrote on 11 Nov 2021, 11:22 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 J.Hilk
                    11 Nov 2021, 11:20

                    @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);
                    
                    A Offline
                    A Offline
                    artwaw
                    wrote on 11 Nov 2021, 11:27 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 1 Reply Last reply 11 Nov 2021, 11:44
                    0
                    • A artwaw
                      11 Nov 2021, 10:45

                      @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 Online
                      J Online
                      jsulm
                      Lifetime Qt Champion
                      wrote on 11 Nov 2021, 11:36 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

                      A 1 Reply Last reply 11 Nov 2021, 11:42
                      1
                      • J jsulm
                        11 Nov 2021, 11:36

                        @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.

                        A Offline
                        A Offline
                        artwaw
                        wrote on 11 Nov 2021, 11:42 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
                        • A artwaw
                          11 Nov 2021, 11:27

                          @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 Online
                          J Online
                          J.Hilk
                          Moderators
                          wrote on 11 Nov 2021, 11:44 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
                          • A Offline
                            A Offline
                            artwaw
                            wrote on 11 Nov 2021, 14:05 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 11 Nov 2021, 20:04 last edited by mpergand 11 Dec 2021, 20:33
                              #13

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

                              A 1 Reply Last reply 11 Nov 2021, 20:12
                              0
                              • M mpergand
                                11 Nov 2021, 20:04

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

                                A Offline
                                A Offline
                                artwaw
                                wrote on 11 Nov 2021, 20:12 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

                                4/14

                                11 Nov 2021, 10:51

                                topic:navigator.unread, 10
                                • Login

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