ElyMar Posted July 3, 2021 Share Posted July 3, 2021 I'm trying to get page count of pdf files using qpdf.dll(open sourced). QPDF is written in C++, but support some C style API. Using qpdf in C: #include <qpdf/qpdf-c.h> #include <stdio.h> #include <stdlib.h> #include <string.h> int main(int argc, char* argv[]) { char* infile = NULL; char* password = NULL; char* outfile = NULL; qpdf_data qpdf = qpdf_init(); if (((qpdf_read(qpdf, infile, password) & QPDF_ERRORS) == 0) .......... qpdf_read definition: ;/* Calling qpdf_read causes processFile to be called in the C++ ; * API. Basic parsing is performed, but data from the file is ; * only read as needed. For files without passwords, pass a null ; * pointer as the password. ; */ ; QPDF_DLL ; QPDF_ERROR_CODE qpdf_read(qpdf_data qpdf, char const* filename, ; char const* password); My autoit code, of cource don't work. How to get it work? : expandcollapse popup#Include <Array.au3> #include <string.au3> Global $hDLL = DllOpen("qpdf28.dll") $sfilename="test.pdf" If $hDLL = -1 then msgbox(0,"","dllOpen() error") ;-1=dllopen() error. ;/* Returns the version of the qpdf software */ ;QPDF_DLL ;char const* qpdf_get_qpdf_version(); $qpdfversion = DllCall($hDLL, "STR*", "qpdf_get_qpdf_version") If @error Then msgbox(0,"", "Dllcall qpdf_get_qpdf_version error. error code: "&@error) msgbox(0,"qpdfversion",$qpdfversion[0]);Works ;typedef struct _qpdf_data* qpdf_data; ;typedef struct _qpdf_error* qpdf_error; ; /* Returns dynamically allocated qpdf_data pointer; must be freed ; * by calling qpdf_cleanup. ; */ ; QPDF_DLL ; qpdf_data qpdf_init(); $qpdfhdl=DllCall($hDLL, "PTR", "qpdf_init") ;Since the returned type is qpdf_data, which is a qpdf_data pointer, can I use PTR? Or have create a struct? but how? If @error Then msgbox(0,"", "Dllcall qpdf_init error. error code: "&@error) msgbox(0,"qpfhdl",$qpdfhdl[0]) ;Seems works; ;typedef int QPDF_ERROR_CODE; ;# define QPDF_SUCCESS 0 ;# define QPDF_WARNINGS 1 << 0 ;# define QPDF_ERRORS 1 << 1 ;/* Calling qpdf_read causes processFile to be called in the C++ ; * API. Basic parsing is performed, but data from the file is ; * only read as needed. For files without passwords, pass a null ; * pointer as the password. ; */ ; QPDF_DLL ; QPDF_ERROR_CODE qpdf_read(qpdf_data qpdf, char const* filename, ; char const* password); $pdfopen = DllCall($hDLL, "INT:cdecl", "qpdf_read","PTR",$qpdfhdl[0],"STR*",$sfilename,"STR*",null) ;I don't know how to make this work. If @error Then msgbox(0,"", "Dllcall qpdf_read error. error code: "&@error) msgbox(0,"pdfoen",$pdfopen[0]) ; /* Return the version of the PDF file. See warning above about ; * functions that return char*. */ ; QPDF_DLL ; char const* qpdf_get_pdf_version(qpdf_data qpdf); $pdfversion = DllCall($hDLL, "STR*:cdecl", "qpdf_get_pdf_version","PTR",$qpdfhdl[0]) ;I don't know how to make it work. If @error Then msgbox(0,"", "Dllcall qpdf_get_pdf_version error. error code: "&@error) msgbox(0,"pdfversion",$pdfversion[0]) ; /* Pass a pointer to the qpdf_data pointer created by qpdf_init to ; * clean up resources. ; */ ; QPDF_DLL ; void qpdf_cleanup(qpdf_data* qpdf); $qpdfcleanup = DllCall($hDLL, "NONE:cdecl", "qpdf_cleanup","PTR*",$qpdfhdl[0]); don't work and cause autoit crash. If @error Then msgbox(0,"", "Dllcall pqdf_cleanup error. error code: "&@error) msgbox(0,"pdfcleanup",$qpdfcleanup[0]) DllClose($hDLL) I'm a autoit newb. dllAndCheader.7z Link to comment Share on other sites More sharing options...
ElyMar Posted July 3, 2021 Author Share Posted July 3, 2021 After trial and error for hours, I managed to get it work, even I don't know why it works. expandcollapse popup#Include <Array.au3> #include <string.au3> Global $hDLL = DllOpen("qpdf28.dll") $sfilename="test.pdf" If $hDLL = -1 then msgbox(0,"","dllOpen() error") ;-1=dllopen() error. ;/* Returns the version of the qpdf software */ ;QPDF_DLL ;char const* qpdf_get_qpdf_version(); $qpdfversion = DllCall($hDLL, "STR*:cdecl", "qpdf_get_qpdf_version") If @error Then msgbox(0,"", "Dllcall qpdf_get_qpdf_version error. error code: "&@error) msgbox(0,"qpdfversion",$qpdfversion[0]);Works ;typedef struct _qpdf_data* qpdf_data; ;typedef struct _qpdf_error* qpdf_error; ; /* Returns dynamically allocated qpdf_data pointer; must be freed ; * by calling qpdf_cleanup. ; */ ; QPDF_DLL ; qpdf_data qpdf_init(); $qpdfhdl=DllCall($hDLL, "PTR:cdecl", "qpdf_init") ;Since the returned type is qpdf_data, which is a qpdf_data pointer, can I use PTR? If @error Then msgbox(0,"", "Dllcall qpdf_init error. error code: "&@error) ;msgbox(0,"qpfhdl",$qpdfhdl[0]) ;Seems works; ;typedef int QPDF_ERROR_CODE; ;# define QPDF_SUCCESS 0 ;# define QPDF_WARNINGS 1 << 0 ;# define QPDF_ERRORS 1 << 1 ;/* Calling qpdf_read causes processFile to be called in the C++ ; * API. Basic parsing is performed, but data from the file is ; * only read as needed. For files without passwords, pass a null ; * pointer as the password. ; */ ; QPDF_DLL ; QPDF_ERROR_CODE qpdf_read(qpdf_data qpdf, char const* filename, ; char const* password); $pdfopen = DllCall($hDLL, "INT:cdecl", "qpdf_read","PTR",$qpdfhdl[0],"STR",$sfilename,"STR",Null) ;I don't know how to make this work. If @error Then msgbox(0,"", "Dllcall qpdf_read error. error code: "&@error) ;msgbox(0,"pdfoen",$pdfopen[0]) ; /* Return the version of the PDF file. See warning above about ; * functions that return char*. */ ; QPDF_DLL ; char const* qpdf_get_pdf_version(qpdf_data qpdf); $pdfversion = DllCall($hDLL, "STR*:cdecl", "qpdf_get_pdf_version","PTR",$qpdfhdl[0]) If @error Then msgbox(0,"", "Dllcall qpdf_get_pdf_version error. error code: "&@error) msgbox(0,"pdfversion",$pdfversion[0]) ; /* Object handling. ; * ; * These methods take and return a qpdf_oh, which is just an ; * unsigned integer. The value 0 is never returned, which makes it ; * usable as an uninitialized value. ;QPDF_DLL ;qpdf_oh qpdf_get_root(qpdf_data data); $pdfroot = DllCall($hDLL, "INT:cdecl", "qpdf_get_root","PTR",$qpdfhdl[0]) msgbox(0,"pdfrootobjnum",$pdfroot[0]) ; QPDF_DLL ; QPDF_BOOL qpdf_oh_is_dictionary(qpdf_data data, qpdf_oh oh); $pdfrootisdict = DllCall($hDLL, "boolean:cdecl", "qpdf_oh_is_dictionary","PTR",$qpdfhdl[0],"int",$pdfroot[0]) msgbox(0,"pdfrootisdict",$pdfrootisdict[0]) ; QPDF_DLL ; qpdf_oh qpdf_oh_get_key(qpdf_data data, qpdf_oh oh, char const* key); $pdfpagesobjnum = DllCall($hDLL, "INT:cdecl", "qpdf_oh_get_key","PTR",$qpdfhdl[0],"int",$pdfroot[0],"STR","/Pages") msgbox(0,"pagesobjnum",$pdfpagesobjnum[0]) $pdfpagescount = DllCall($hDLL, "INT:cdecl", "qpdf_oh_get_key","PTR",$qpdfhdl[0],"int",$pdfpagesobjnum[0],"STR","/Count") ;msgbox(0,"pagescount",$pdfpagescount[0]) ; QPDF_DLL ; char const* qpdf_oh_unparse_resolved(qpdf_data data, qpdf_oh oh); $pdfPages = DllCall($hDLL, "STR*:cdecl", "qpdf_oh_unparse_resolved","PTR",$qpdfhdl[0],"int",$pdfpagescount[0]) msgbox(0,"pdfTotalPages",$pdfPages[0]) ; /* Pass a pointer to the qpdf_data pointer created by qpdf_init to ; * clean up resources. ; */ ; QPDF_DLL ; void qpdf_cleanup(qpdf_data* qpdf); $qpdfcleanup = DllCall($hDLL, "NONE:cdecl", "qpdf_cleanup","PTR*",$qpdfhdl[0]); PTR will crash, but PTR* not why? If @error Then msgbox(0,"", "Dllcall pqdf_cleanup error. error code: "&@error) msgbox(0,"pdfcleanup",$qpdfcleanup[0]) DllClose($hDLL) Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now