wrapper for cpdf library, possible?

Just starting out? Need help? Post your questions and find answers here.
morosh
Enthusiast
Enthusiast
Posts: 335
Joined: Wed Aug 03, 2011 4:52 am
Location: Beirut, Lebanon

wrapper for cpdf library, possible?

Post by morosh »

Hello:
I've discovered recently cpdf (https://community.coherentpdf.com), which provides a "libcpdf.dll" for pdf manipulations, which is free for personal use,
can this dll be used from Pb? I tried the following with no success:

Code: Select all

hdl = OpenLibrary(#PB_Any, "E:\install\dvd2\PDF utilities\cpdf\libcpdf.dll")

If hdl
  Prototype cpdf_startup(ID, ErrorOutput)
  Define cpdf_startup.cpdf_startup = GetFunction(hdl, "cpdf_startup")
  
EndIf
Define ErrorOutput$ = ""

cpdf_startup(0, @ErrorOutput$);

CloseLibrary(hdl)

I got IMA (error read at address 0)
I've no experience writing wrappers.
any help is appreciated.

thanks
PureBasic: Surprisingly simple, diabolically powerful
User avatar
idle
Always Here
Always Here
Posts: 6035
Joined: Fri Sep 21, 2007 5:52 am
Location: New Zealand

Re: wrapper for cpdf library, possible?

Post by idle »

using PB 6 c backend

if you haven't done so already, compile the pbcex tools gcc and polink
https://www.purebasic.fr/english/viewtopic.php?t=79332

Then use polib to make an import library to the dll
polib E:\cpdflib-binary-master\windows64\libcpdf.dll

Then save this in the windows64 dir, edit the paths to the files and it will print 2.5.2

Code: Select all

ImportC "e:\cpdflib-binary-master\windows64\libcpdf.lib"
  cpdf_startup(*v) 
  cpdf_version() 
EndImport 

!//#include E:\cpdflib-binary-master\windows64\cpdflibwrapper.h;

Global res 
Global *out 

cpdf_startup(@res);        
!p_out = cpdf_version();  //;call in c no need to import the function 

If *out 
   Debug PeekS(*out,-1,#PB_UTF8) ;if it worked print the verions 
EndIf 


*out = cpdf_version() ;call the pb imported function 
If *out 
  Debug  PeekS(*out,-1,#PB_UTF8) ;If it worked print the verions  
EndIf   
you can add pb imports as you need or want or just call the c lib directly.
It makes it a lot easier to work with c libs you just need to remember that PB symbols are all lower case in c and prefixed as v_ for a var p_ for a pointer and f_ for a function and address @ is &
infratec
Always Here
Always Here
Posts: 7664
Joined: Sun Sep 07, 2008 12:45 pm
Location: Germany

Re: wrapper for cpdf library, possible?

Post by infratec »

I don't know from where you got the parameters of cpdf_startup().
The parameters of the functions are in cpdflibwrapper.h

You need 2 dll files for x86:
libcpdf.dll
libgcc_s_sjlj-1.dll

Code: Select all

;
; https://community.coherentpdf.com/
;

CompilerIf #PB_Compiler_IsMainFile
  EnableExplicit
CompilerEndIf

; CHAPTER 0. Preliminaries
PrototypeC prototype_cpdf_startup(*argv)
PrototypeC.i prototype_cpdf_version()
PrototypeC prototype_cpdf_setFast()
PrototypeC prototype_cpdf_setSlow()
PrototypeC prototype_cpdf_onExit()

; CHAPTER 1. Basics
PrototypeC.i prototype_cpdf_fromFile(filename.p-utf8, userpw.p-utf8)
PrototypeC.i prototype_cpdf_fromFileLazy(pdf.p-utf8, userpw.p-utf8)
PrototypeC.i prototype_cpdf_fromMemory(*Data, length.l, userpw.p-utf8)
PrototypeC.i prototype_cpdf_fromMemoryLazy(*Data, length.l, userpw.p-utf8)
PrototypeC prototype_cpdf_deletePdf(pdf.l)
PrototypeC prototype_cpdf_replacePdf(a.l, b.l)

PrototypeC prototype_cpdf_clearError()
PrototypeC.i prototype_cpdf_mergeSimple(*pdfs, length.l)
PrototypeC prototype_cpdf_toFile(pdf.l, filename.p-utf8, linearize.l, make_id.l)


Global cpdf_library.i

; CHAPTER 0. Preliminaries
Global cpdf_startup.prototype_cpdf_startup
Global cpdf_version_.prototype_cpdf_version
Global cpdf_setFast.prototype_cpdf_setFast
Global cpdf_setSlow.prototype_cpdf_setSlow
Global.i cpdf_lastError_
Global.i cpdf_lastErrorString_
Global cpdf_onExit.prototype_cpdf_onExit

; CHAPTER 1. Basics
Global cpdf_fromFile.prototype_cpdf_fromFile
Global cpdf_fromFileLazy.prototype_cpdf_fromFileLazy
Global cpdf_fromMemory.prototype_cpdf_fromMemory
Global cpdf_fromMemoryLazy.prototype_cpdf_fromMemoryLazy
Global cpdf_deletePdf.prototype_cpdf_deletePdf
Global cpdf_replacePdf.prototype_cpdf_replacePdf

; CHAPTER 2. Merging And Splitting
Global cpdf_mergeSimple.prototype_cpdf_mergeSimple

; CHAPTER 3. Pages

; CHAPTER 4. Encryption
; Encryption covered under Chapter 1 in cpdflib.

; CHAPTER 5. Compression

; CHAPTER 6. Bookmarks

; CHAPTER 7. Presentations

; Not included in the library version.

; CHAPTER 8. Logos, Watermarks And Stamps

Global cpdf_clearError.prototype_cpdf_clearError
Global cpdf_toFile.prototype_cpdf_toFile



Macro cpdf_version()
  PeekS(cpdf_version_(), -1, #PB_UTF8)
EndMacro

Macro cpdf_lastError
  PeekI(cpdf_lastError_)
EndMacro

Macro cpdf_lastErrorString
  PeekS(cpdf_lastErrorString_, -1, #PB_UTF8)
EndMacro


Procedure.i OpenCPDF()
  
  If Not IsLibrary(cpdf_library)
    cpdf_library = OpenLibrary(#PB_Any, "libcpdf.dll")
    If cpdf_library
      ; CHAPTER 0. Preliminaries
      cpdf_startup          = GetFunction(cpdf_library, "cpdf_startup")
      cpdf_version_         = GetFunction(cpdf_library, "cpdf_version")
      cpdf_setFast          = GetFunction(cpdf_library, "cpdf_setFast")
      cpdf_setSlow          = GetFunction(cpdf_library, "cpdf_setSlow")
      cpdf_lastError_       = GetFunction(cpdf_library, "cpdf_lastError")
      cpdf_lastErrorString_ = GetFunction(cpdf_library, "cpdf_lastErrorString")
      cpdf_onExit           = GetFunction(cpdf_library, "cpdf_onExit")
      
      ; CHAPTER 1. Basics
      cpdf_fromFile         = GetFunction(cpdf_library, "cpdf_fromFile")
      cpdf_fromFileLazy     = GetFunction(cpdf_library, "cpdf_fromFileLazy")
      cpdf_fromMemory       = GetFunction(cpdf_library, "cpdf_fromMemory")
      cpdf_fromMemoryLazy   = GetFunction(cpdf_library, "cpdf_fromMemoryLazy")
      cpdf_deletePdf        = GetFunction(cpdf_library, "cpdf_deletePdf")
      cpdf_replacePdf       = GetFunction(cpdf_library, "cpdf_replacePdf")
      
      ; CHAPTER 2. Merging And Splitting
      cpdf_mergeSimple      = GetFunction(cpdf_library, "cpdf_mergeSimple")
      
      ; CHAPTER 3. Pages
      
      cpdf_toFile           = GetFunction(cpdf_library, "cpdf_toFile")
      cpdf_clearError       = GetFunction(cpdf_library, "cpdf_clearError")
      
      
    EndIf
  EndIf
  
  ProcedureReturn cpdf_library
  
EndProcedure


Procedure CloseCPDF()
  If IsLibrary(cpdf_library)
    CloseLibrary(cpdf_library)
    cpdf_library = #Null
  EndIf
EndProcedure



CompilerIf #PB_Compiler_IsMainFile
  
  Define *argv
  Define.i mergepdf, merged
  Dim pdfs.l(2)
  
  If OpenCPDF()
    
    ; Initialise cpdf
    cpdf_startup(@*argv)
    
    Debug cpdf_version()
    
    ; We will take the input hello.pdf And Repeat it three times
    mergepdf = cpdf_fromFile("hello.pdf", "")
    
    ; Check the error state
    If cpdf_lastError = 1
      Debug cpdf_lastErrorString
      End 1
    EndIf
    
    ; Clear the error state
    cpdf_clearError()
    
    ; The Array of PDFs To merge
    pdfs(0) = mergepdf
    pdfs(1) = mergepdf
    pdfs(2) = mergepdf
    
    ; Merge them
    merged = cpdf_mergeSimple(pdfs(), 3)
    
    ; Check the error state
    If cpdf_lastError = 1
      Debug cpdf_lastErrorString
      End 1
    EndIf
    
    cpdf_clearError()
    
    ; Write output
    cpdf_toFile(merged, "merged.pdf", #False, #False)
    
    ; Check the error state
    If cpdf_lastError = 1
      Debug cpdf_lastErrorString
      End 1
    EndIf
      
    CloseCPDF()
  EndIf
  
CompilerEndIf
I don't know if the cpdf_lastError... stuff is working.
The example is from page 11 of cpdflibmanual.pdf
Last edited by infratec on Thu Jun 16, 2022 10:10 pm, edited 3 times in total.
morosh
Enthusiast
Enthusiast
Posts: 335
Joined: Wed Aug 03, 2011 4:52 am
Location: Beirut, Lebanon

Re: wrapper for cpdf library, possible?

Post by morosh »

Thank you both:
@idle: yes, I'll try that later
@infratec: thank you very much, but it crash at the line: cpdf_toFile(merged, "merged.pdf", #False, #False)
saying: The debugged executable quit unexpectedly.
About libgcc_s_sjlj-1.dll, it's not opened in the snippet, do you mean it's used by libcpdf.dll?
Anyway I copied it from: Dev-Cpp 6.3\TDM-GCC-64\bin, is it correct?
both dll are now in the same folder as the source file.

Thanks again
PureBasic: Surprisingly simple, diabolically powerful
infratec
Always Here
Always Here
Posts: 7664
Joined: Sun Sep 07, 2008 12:45 pm
Location: Germany

Re: wrapper for cpdf library, possible?

Post by infratec »

I used the win32 files from:

https://github.com/coherentgraphics/cpd ... master.zip

Maybe you are on x64.

And yes, the gcc lib is needed by the cpdf lib.
infratec
Always Here
Always Here
Posts: 7664
Joined: Sun Sep 07, 2008 12:45 pm
Location: Germany

Re: wrapper for cpdf library, possible?

Post by infratec »

Ok, you are using the x64 version.

There is no gcc lib.

I changed the pdf array from .i to .l
Now it works also with x64.
morosh
Enthusiast
Enthusiast
Posts: 335
Joined: Wed Aug 03, 2011 4:52 am
Location: Beirut, Lebanon

Re: wrapper for cpdf library, possible?

Post by morosh »

Thanks very much
Now it's working in both 32 and 64 (libgcc_s_sjlj-1.dll should be in the current folder).
At first, I couldn't download it from cpdf site because my antivirus flags it as risky.

@idle: seems like you converted the dll to a static lib, correct? very interesting if so.

Regards
PureBasic: Surprisingly simple, diabolically powerful
User avatar
idle
Always Here
Always Here
Posts: 6035
Joined: Fri Sep 21, 2007 5:52 am
Location: New Zealand

Re: wrapper for cpdf library, possible?

Post by idle »

No it's just an import library to the dll. It just makes it easier to work with. While there is a static lib version it probably won't be compatible with pb though I didn't try it.
infratec
Always Here
Always Here
Posts: 7664
Joined: Sun Sep 07, 2008 12:45 pm
Location: Germany

Re: wrapper for cpdf library, possible?

Post by infratec »

.a is the static lib, but ...

it s not usable with pb. Even if you convert it from .a to .lib, there are many references to gcc libc functions inside.
morosh
Enthusiast
Enthusiast
Posts: 335
Joined: Wed Aug 03, 2011 4:52 am
Location: Beirut, Lebanon

Re: wrapper for cpdf library, possible?

Post by morosh »

Trying to add function addText (that's why I'm interested in this lib) by myself, I didn't succeed:

Code: Select all

CompilerIf #PB_Compiler_IsMainFile
  EnableExplicit
CompilerEndIf

Structure cpdf_position 
  cpdf_anchor.l;    /* Position anchor */
  cpdf_coord1.d;    /* Parameter one */
  cpdf_coord2.d;    /* Parameter two */
EndStructure

Enumeration cpdf_anchor 
  #cpdf_posCentre;      /* Absolute centre */
  #cpdf_posLeft ;       /* Absolute left */
  #cpdf_posRight;       /* Absolute right */
  #cpdf_top;            /* Top top centre of the page */
  #cpdf_topLeft;        /* The top left of the page */
  #cpdf_topRight;       /* The top right of the page */
  #cpdf_left;           /* The left hand side of the page, halfway down */
  #cpdf_bottomLeft;     /* The bottom left of the page */
  #cpdf_bottom;         /* The bottom middle of the page */
  #cpdf_bottomRight;    /* The bottom right of the page */
  #cpdf_right;          /* The right hand side of the page, halfway down */
  #cpdf_diagonal;       /* Diagonal, bottom left To top right */
  #cpdf_reverseDiagonal; /* Diagonal, top left To bottom right */
EndEnumeration

Enumeration cpdf_font 
  #cpdf_timesRoman   ;           /* Times Roman */
  #cpdf_timesBold    ;            /* Times Bold */
  #cpdf_timesItalic  ;          /* Times Italic */
  #cpdf_timesBoldItalic  ;      /* Times Bold Italic */
  #cpdf_helvetica    ;            /* Helvetica */
  #cpdf_helveticaBold  ;        /* Helvetica Bold */
  #cpdf_helveticaOblique ;     /* Helvetica Oblique */
  #cpdf_helveticaBoldOblique ; /* Helvetica Bold Oblique */
  #cpdf_courier      ;              /* Courier */
  #cpdf_courierBold  ;          /* Courier Bold */
  #cpdf_courierOblique   ;       /* Courier Oblique */
  #cpdf_courierBoldOblique   ;    /* Courier Bold Oblique */
EndEnumeration

Enumeration cpdf_justification
  #cpdf_leftJustify    ;   /* Left justify */
  #cpdf_CentreJustify  ; /* Centre justify */
  #cpdf_RightJustify   ;   /* Right justify */
EndEnumeration

PrototypeC.i prototype_cpdf_version()
PrototypeC prototype_cpdf_startup(*argv)
PrototypeC.i prototype_cpdf_fromFile(filename.p-utf8, userpw.p-utf8)
PrototypeC prototype_cpdf_clearError()
PrototypeC.i prototype_cpdf_mergeSimple(*pdfs, length.l)
PrototypeC prototype_cpdf_toFile(pdf.l, filename.p-utf8, linearize.l, make_id.l)
PrototypeC prototype_cpdf_pages(pdf.l)
PrototypeC prototype_cpdf_addText(flag_add.l, pdf.l, page.l, txt.p-utf8, *position.cpdf_position, linespacing.d,
           stbates.l, font.i, size.d, red.d, green.d, blue.d, flagunder.l, flagcrop.l, flagoutline.l, opacity.d,
           justification.i, flag_midline.l, flag_topline.l, fname.p-utf8, linewidth.d, embed.l)
PrototypeC prototype_cpdf_addTextSimple(pdf.l, page.l, txt.p-utf8, *position.cpdf_position, font.i, size.d)

Global cpdf_library.i
Global cpdf_version_.prototype_cpdf_version
Global cpdf_startup.prototype_cpdf_startup
Global cpdf_fromFile.prototype_cpdf_fromFile
Global cpdf_clearError.prototype_cpdf_clearError
Global cpdf_mergeSimple.prototype_cpdf_mergeSimple
Global cpdf_toFile.prototype_cpdf_toFile
Global cpdf_pages.prototype_cpdf_pages
Global cpdf_addText.prototype_cpdf_addText
Global cpdf_addTextSimple.prototype_cpdf_addTextSimple

Global.i cpdf_lastError_
Global.i cpdf_lastErrorString_

Macro cpdf_version()
  PeekS(cpdf_version_(), -1, #PB_UTF8)
EndMacro

Macro cpdf_lastError
  PeekI(cpdf_lastError_)
EndMacro

Macro cpdf_lastErrorString
  PeekS(cpdf_lastErrorString_, -1, #PB_UTF8)
EndMacro


Procedure.i OpenCPDF()
  
  If Not IsLibrary(cpdf_library)
    CompilerIf #PB_Compiler_Processor = #PB_Processor_x86
      cpdf_library = OpenLibrary(#PB_Any, "E:\install\dvd2\PDF utilities\sdk\cpdf\win32\libcpdf.dll")
    CompilerElseIf #PB_Compiler_Processor = #PB_Processor_x64
      cpdf_library = OpenLibrary(#PB_Any, "E:\install\dvd2\PDF utilities\sdk\cpdf\win64\libcpdf.dll")
    CompilerEndIf
      
    If cpdf_library
      cpdf_version_         = GetFunction(cpdf_library, "cpdf_version")
      cpdf_startup          = GetFunction(cpdf_library, "cpdf_startup")
      cpdf_fromFile         = GetFunction(cpdf_library, "cpdf_fromFile")
      cpdf_clearError       = GetFunction(cpdf_library, "cpdf_clearError")
      cpdf_mergeSimple      = GetFunction(cpdf_library, "cpdf_mergeSimple")
      cpdf_toFile           = GetFunction(cpdf_library, "cpdf_toFile")
      cpdf_pages            = GetFunction(cpdf_library, "cpdf_pages")
      cpdf_addText          = GetFunction(cpdf_library, "cpdf_addText")
      cpdf_addTextSimple    = GetFunction(cpdf_library, "cpdf_addTextSimple")
                   
      cpdf_lastError_       = GetFunction(cpdf_library, "cpdf_lastError")
      cpdf_lastErrorString_ = GetFunction(cpdf_library, "cpdf_lastErrorString")
    Else 
      MessageRequester("Error","no libcpdf.dll present")
    EndIf
  EndIf
  
  ProcedureReturn cpdf_library
  
EndProcedure

Procedure CloseCPDF()
  If IsLibrary(cpdf_library)
    CloseLibrary(cpdf_library)
    cpdf_library = #Null
  EndIf
EndProcedure

CompilerIf #PB_Compiler_IsMainFile
  
  Define *argv
  Define.i orig_pdf, output
  Dim pdfs.l(2)
  Global pos.cpdf_position
  
  pos\cpdf_anchor=#cpdf_posCentre     ;    /* Position anchor */
  pos\cpdf_coord1=100    ; /* Parameter one */
  pos\cpdf_coord2=100   ; /* Parameter two */

  If OpenCPDF()
    
    ; Initialise cpdf
    cpdf_startup(@*argv)
    
    ;Debug cpdf_version()
    
    ; We will take the input hello.pdf And Repeat it three times
    orig_pdf = cpdf_fromFile("hello.pdf", "")
    
    ; Check the error state
    If cpdf_lastError = 1
      Debug cpdf_lastErrorString
      End 1
    EndIf
    
    ; Clear the error state
    cpdf_clearError()
    
    ; The Array of PDFs To merge
    pdfs(0) = orig_pdf
    pdfs(1) = orig_pdf
    pdfs(2) = orig_pdf
    
    ; Merge them
    output = cpdf_mergeSimple(pdfs(), 3)
;     cpdf_addText(#False, output, 1, "hello!!!", @pos, 1, 0, #cpdf_helveticaBoldOblique, 14, 0.5, 0.5, 0.5, #False, #False,
;                  #False, 1, #cpdf_CentreJustify, #False, #False, "xxx", 5, #False)
    cpdf_addTextSimple(output, 1, "hello!!!", @pos, #cpdf_helveticaBoldOblique, 14)
    
    ; Check the error state
    If cpdf_lastError = 1
      Debug cpdf_lastErrorString
      End 1
    EndIf
    
    cpdf_clearError()
    
    ; Write output
    cpdf_toFile(output, "output.pdf", #False, #False)
    Debug cpdf_pages(output)
    ; Check the error state
    If cpdf_lastError = 1
      Debug cpdf_lastErrorString
      End 1
    EndIf
      
    CloseCPDF()
  EndIf
CompilerEndIf
"The debugged executable quit unexpectedly." always at line "cpdf_addTextSimple(output, 1, "hello!!!", @pos, #cpdf_helveticaBoldOblique, 14)"

any help is appreciated.

Regards
PureBasic: Surprisingly simple, diabolically powerful
Post Reply