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