Incompatible pointer type when referencing the method.
-
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 asprivate: 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 -
@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.
-
@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. -
@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);
-
@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.
-
@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...
-
@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.
-
@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.