Jump to content

Help needed using dllcall containing struct ?


Recommended Posts

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

#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 post
Share on other sites

After trial and error for hours, I managed to get it work, even I don't know why it works.

#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 post
Share on other sites

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 account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    No registered users viewing this page.

×
×
  • Create New...