Bonjour à tous,
Pour ma culture personnelle et pour améliorer mes connaissance sur AutoIt je me suis lancé dans une petit projet. A savoir, convertir des pdf en tif.
Après quelques recherches sur le sujet et savoir si c'est faisable avec AutoIt, je me suis dirigé vers GhostScript.
Ma première phase a été réussi avec succès, à savoir en faisant appel à la lib gsdll avec l'exe de GhostScript.
Maintenant j'aimerais approfondir mes connaissances sur l'utilisation des dll directement dans mon script (et donc de ne plus être dépendant de l'exe)
J'ai donc créé mes fonctions (création de l'instance, clôture de l'instance, etc.)
Cependant, je bloque sur la partie la plus importante

=> l'appel de la fonction pour convertir.
Voici la doc:
La fonction:
Code : Tout sélectionner
int gsapi_init_with_args (void *instance, int argc, char **argv);
Un exemple tiré de la doc:
► Afficher le texteExemple
Code : Tout sélectionner
Example of using GS DLL as a ps2pdf converter. */
#if defined(_WIN32) && !defined(_Windows)
# define _Windows
#endif
#ifdef _Windows
/* add this source to a project with gsdll32.dll, or compile it directly with:
* cl -D_Windows -Isrc -Febin\ps2pdf.exe ps2pdf.c bin\gsdll32.lib
*/
# include <windows.h>
# define GSDLLEXPORT __declspec(dllimport)
#endif
#include "ierrors.h"
#include "iapi.h"
void *minst;
int main(int argc, char *argv[])
{
int code, code1;
const char * gsargv[10];
int gsargc;
gsargv[0] = "ps2pdf"; /* actual value doesn't matter */
gsargv[1] = "-dNOPAUSE";
gsargv[2] = "-dBATCH";
gsargv[3] = "-dSAFER";
gsargv[4] = "-sDEVICE=pdfwrite";
gsargv[5] = "-sOutputFile=out.pdf";
gsargv[6] = "-c";
gsargv[7] = ".setpdfwrite";
gsargv[8] = "-f";
gsargv[9] = "input.ps";
gsargc=10;
code = gsapi_new_instance(&minst, NULL);
if (code < 0)
return 1;
code = gsapi_set_arg_encoding(minst, GS_ARG_ENCODING_UTF8);
if (code == 0)
code = gsapi_init_with_args(minst, gsargc, gsargv);
code1 = gsapi_exit(minst);
if ((code == 0) || (code == e_Quit))
code = code1;
gsapi_delete_instance(minst);
if ((code == 0) || (code == e_Quit))
return 0;
return 1;
}
Un second exemple en VB (dont je me suis pas mal inspiré):
► Afficher le texteExemple VB
Code : Tout sélectionner
Option Explicit On
Imports System.Runtime.InteropServices
'--- Simple VB.Net wrapper for Ghostscript gsdll32.dll
' (Tested using Visual Studio 2010 and Ghostscript 9.06)
'http://stackoverflow.com/questions/16929383/simple-vb-net-wrapper-for-ghostscript-dll
'http://www.ghostscript.com/doc/current/API.htm
Module GhostscriptDllLib
Private Declare Function gsapi_new_instance Lib "gsdll32.dll" _
(ByRef instance As IntPtr, _
ByVal caller_handle As IntPtr) As Integer
Private Declare Function gsapi_set_stdio Lib "gsdll32.dll" _
(ByVal instance As IntPtr, _
ByVal gsdll_stdin As StdIOCallBack, _
ByVal gsdll_stdout As StdIOCallBack, _
ByVal gsdll_stderr As StdIOCallBack) As Integer
Private Declare Function gsapi_init_with_args Lib "gsdll32.dll" _
(ByVal instance As IntPtr, _
ByVal argc As Integer, _
<MarshalAs(UnmanagedType.LPArray, ArraySubType:=UnmanagedType.LPStr)> _
ByVal argv() As String) As Integer
Private Declare Function gsapi_exit Lib "gsdll32.dll" _
(ByVal instance As IntPtr) As Integer
Private Declare Sub gsapi_delete_instance Lib "gsdll32.dll" _
(ByVal instance As IntPtr)
'--- Run Ghostscript with specified arguments
Public Function RunGS(ByVal ParamArray Args() As String) As Boolean
Dim InstanceHndl As IntPtr
Dim NumArgs As Integer
Dim StdErrCallback As StdIOCallBack
Dim StdInCallback As StdIOCallBack
Dim StdOutCallback As StdIOCallBack
NumArgs = Args.Count
StdInCallback = AddressOf InOutErrCallBack
StdOutCallback = AddressOf InOutErrCallBack
StdErrCallback = AddressOf InOutErrCallBack
'--- Shift arguments to begin at index 1 (Ghostscript requirement)
ReDim Preserve Args(NumArgs)
System.Array.Copy(Args, 0, Args, 1, NumArgs)
'--- Start a new Ghostscript instance
If gsapi_new_instance(InstanceHndl, 0) <> 0 Then
Return False
Exit Function
End If
'--- Set up dummy callbacks
gsapi_set_stdio(InstanceHndl, StdInCallback, StdOutCallback, StdErrCallback)
'--- Run Ghostscript using specified arguments
gsapi_init_with_args(InstanceHndl, NumArgs + 1, Args)
'--- Exit Ghostscript
gsapi_exit(InstanceHndl)
'--- Delete instance
gsapi_delete_instance(InstanceHndl)
Return True
End Function
'--- Delegate function for callbacks
Private Delegate Function StdIOCallBack(ByVal handle As IntPtr, _
ByVal Strz As IntPtr, ByVal Bytes As Integer) As Integer
'--- Dummy callback for standard input, standard output, and errors
Private Function InOutErrCallBack(ByVal handle As IntPtr, _
ByVal Strz As IntPtr, ByVal Bytes As Integer) As Integer
Return 0
End Function
Le Main:
Sub Main()
'================================================================
Dim PdfFilePath As String = "In.pdf"
Dim TifFilePath As String = "out.tif"
Dim Args() As String = {"-q", "-dNOPAUSE", "-dBATCH", "-dSAFER", _
"-sDEVICE=tiffg4", "-r300", _
"-sOutputFile=" & TifFilePath, PdfFilePath}
RunGS(Args)
End Sub
Mais en essayant de transcrit ces fonctions en AutoIt, je suis confronté à un problème. L'appel des arguments dans la fonction.
Voici ce que j'ai mis:
Code : Tout sélectionner
$aRet = DllCall("gsdll32.dll","int","gsapi_init_with_args","int",$hInstance,"int",$iArgCount,"str",$aArgument)
$aArgument = l'Array des arguements (voir exemple1)
L'appel directement de l'array dans dllCall = Plantage AutoIt
Le passage par une DllStructureCreate = message du Callback (Error: /undefinedfilename in (\250,\237\001\250,\237\001\200\001?)" <= Ca c'est du nom de fichier

)
L'Erreur doit se situer dans la construction de la Structure (dont je n'ai certainement pas compris le fonctionnement...cf ci-dessous
► Afficher le texteMa fonction
Code : Tout sélectionner
Func __DllStructCreate($aArray)
Local $sStructure = "",$aStructure = 0
If Not IsArray($aArray) Then Return SetError(1,0,-1)
For $i = 0 To UBound($aArray) - 1
$sStructure = $sStructure & ";char var" & $i & "[" & StringLen($aArray[$i]) & "]"
Next
$sStructure = StringRight($sStructure,StringLen($sStructure) - 1)
ConsoleWrite($sStructure & @CRLF)
$aStructure = DllStructCreate($sStructure)
If @error Then Return SetError(2,0,-1)
For $x = 0 To UBound($aArray) - 1
DllStructSetData($aStructure,"var" & $x,$aArray[$x])
If @error Then Return SetError(3,0,-1)
Next
$Msg = ""
For $i = 0 To DllStructGetSize($aStructure)
If DllStructGetData($aStructure, $i) <> "" THen
$Msg = $Msg & DllStructGetData($aStructure, $i) & @CRLF
EndIF
Next
MsgBox(0, "DllStruct", "Struct Size: " & DllStructGetSize($aStructure) & @CRLF & _
"Struct pointer: " & DllStructGetPtr($aStructure) & @CRLF & _
"Data:" & @CRLF & _
$Msg)
Return $aStructure
EndFunc
Merci d'être indulgent, c'est ma première utilisation des Dll dans mon code
Si quelqu'un pourrait me guider et m'indiquer mes erreurs sur l'appel de plusieurs paramètres dans un DllCall j'en serais ravi.
Merci d'avance.
PS: je posterais tout mon code si besoin ce soir (quand je rentrerais et que j'aurais un peu nettoyé la gueule du truc)