vipergts450 Posted June 20, 2014 Share Posted June 20, 2014 Hi all, I've spent hours poring over the forums to try and find similar examples to mine, but still managed to get stuck at a particular point in the process to invoke the gsdll32.dll functions. I am able to open the DLL, and get a successful response from gsapi_new_instance when passing pointers around there. However, attempting to invoke gsapi_init_with_args has me very frustrated. Here's my code: expandcollapse popupLocal $aDllArgs[9] = ["gswin32c", _ "-sDEVICE=pdfwrite", _ "-dNOPAUSE", _ "-dBATCH", _ "-dSAFER", _ "-dFirstPage=" & $aParseArgs[3], _ "-dLastPage=" & $aParseArgs[4], _ "-sOutputFile=""" & $sDestName & """", _ """" & $sPDFPath & """"] $varList = DllStructCreate("ptr[" & UBound($aDllArgs) & "]") $p_varList = DllStructGetPtr($varList) For $k=1 to UBound($aDllArgs) DllStructSetData( $varList, _ $k, _ DllStructSetData(DllStructCreate("char[255]"), 1, $aDllArgs[$k-1])) Next consolewrite("varList is located at: " & $p_varList & @CRLF) Local $hDll = DllOpen(@ScriptDir & "\gsdll32.dll") Local $hInst ConsoleWrite("hInst prior to call: " & $hInst & @CRLF) Local $dResult = DllCall($hDll, "int", "gsapi_new_instance", "ptr*", Null, "ptr", Null) $hInst = $dResult[1] ConsoleWrite("created instance. returned: " & $dResult[0] & @CRLF & "$hInst: " & $hInst & @CRLF) If $dResult[0] = 0 Then ConsoleWrite("trying to print PDF" & @CRLF) $dResult = DllCall($hDll, "int", "gsapi_init_with_args", "ptr", $hInst, _ "int", UBound($aDllArgs), _ "ptr", $p_varList) Since gsapi_init_with_args takes (void *instance, int argc, char **argv), I figured I needed to convert the items in my $aDllArgs array to DllStructs, then pass the pointer to that DllStruct into the function call since AutoIt doesn't have char** types. Unfortunately this just crashes out once the code reaches this line. However, even when I tried passing the third argument as type "str" or "str*" and $aDllArgs directly: $dResult = DllCall($hDll, "int", "gsapi_init_with_args", "ptr", $hInst, _ "int", UBound($aDllArgs), _ "str*", $aDllArgs) it still crashes out. Not sure where to go from here. Any help would be greatly appreciated. Thanks. Link to comment Share on other sites More sharing options...
LarsJ Posted June 21, 2014 Share Posted June 21, 2014 (edited) Have you checked if $varList contains the proper data? (Hint: You have only one element, which is an array of pointers.) Edited June 21, 2014 by LarsJ Controls, File Explorer, ROT objects, UI Automation, Windows Message MonitorCompiled code: Accessing AutoIt variables, DotNet.au3 UDF, Using C# and VB codeShell menus: The Context menu, The Favorites menu. Shell related: Control Panel, System Image ListsGraphics related: Rubik's Cube, OpenGL without external libraries, Navigating in an image, Non-rectangular selectionsListView controls: Colors and fonts, Multi-line header, Multi-line items, Checkboxes and icons, Incremental searchListView controls: Virtual ListViews, Editing cells, Data display functions Link to comment Share on other sites More sharing options...
Solution Danyfirex Posted June 21, 2014 Solution Share Posted June 21, 2014 (edited) Edit 1. I was Wrong. maybe if you try the C code. then can make it in autoit. Edit 2: $dResult = DllCall($hDll, "int", "gsapi_init_with_args", "ptr", $hInst, "int", UBound($aDllArgs), "str*", $aDllArgs) last dllcall argument should be a pointer to structure $p_varList. look: $dResult = DllCall($hDll, "int", "gsapi_init_with_args", "ptr", $hInst,"int",UBound($aDllArgs), "ptr", $p_varList) Saludos Edit 3 Your structure of pointers is wrong. Try something like this: Local $aDllArgs[9] = ["gswin32c", _ "-sDEVICE=pdfwrite", _ "-dNOPAUSE", _ "-dBATCH", _ "-dSAFER", _ "-dFirstPage=" & $aParseArgs[3], _ "-dLastPage=" & $aParseArgs[4], _ "-sOutputFile=""" & $sDestName & """", _ """" & $sPDFPath & """"] $varList = DllStructCreate("ptr[" & UBound($aDllArgs) & "]") $p_varList = DllStructGetPtr($varList) Local $tData[UBound($aDllArgs)] for $i= 1 to UBound($aDllArgs) $tData[$i-1]=DllStructCreate("char[" & StringLen($aDllArgs[$i-1])+1 & "]") DllStructSetData($varList,1,DllStructGetPtr($tData[$i-1]),$i) ;Debug Pointers ConsoleWrite(DllStructGetData($varList,1,$i) & @CRLF) DllStructSetData($tData[$i-1],1,$aDllArgs[$i-1]) next ;Debug Strings for $i=1 to UBound($aDllArgs) ConsoleWrite(DllStructGetData(DllStructCreate("char[" & StringLen($aDllArgs[$i-1])+1 & "]",DllStructGetData($varList,1,$i)),1) & @CRLF) Next Saludos Edited June 21, 2014 by Danyfirex vipergts450 1 Danysys.com AutoIt... UDFs: VirusTotal API 2.0 UDF - libZPlay UDF - Apps: Guitar Tab Tester - VirusTotal Hash Checker Examples: Text-to-Speech ISpVoice Interface - Get installed applications - Enable/Disable Network connection PrintHookProc - WINTRUST - Mute Microphone Level - Get Connected NetWorks - Create NetWork Connection ShortCut Link to comment Share on other sites More sharing options...
vipergts450 Posted June 22, 2014 Author Share Posted June 22, 2014 Thanks very much for the help LarsJ and Danyfirex. Danyfirex, your solution worked perfectly... I'm still trying to get the hang of the DllStructs and how they are passed from function to function. I'm finding it tough to follow the data through the process of multiple DllStructGetData and DllStructGetPtr functions concatenated like that. Thanks again for the explanation. Link to comment Share on other sites More sharing options...
Danyfirex Posted June 22, 2014 Share Posted June 22, 2014 You're welcome. Saludos Danysys.com AutoIt... UDFs: VirusTotal API 2.0 UDF - libZPlay UDF - Apps: Guitar Tab Tester - VirusTotal Hash Checker Examples: Text-to-Speech ISpVoice Interface - Get installed applications - Enable/Disable Network connection PrintHookProc - WINTRUST - Mute Microphone Level - Get Connected NetWorks - Create NetWork Connection ShortCut Link to comment Share on other sites More sharing options...
MyEarth Posted June 22, 2014 Share Posted June 22, 2014 Sorry for the up, is possible to see a working example? I have always use gswin32c executable but if i can avoid it and use only the DLL is better. Thanks Link to comment Share on other sites More sharing options...
vipergts450 Posted June 22, 2014 Author Share Posted June 22, 2014 Sorry for the up, is possible to see a working example? I have always use gswin32c executable but if i can avoid it and use only the DLL is better. Thanks Certainly. So the gsdll32.dll is a little quirky because you have to initialize it, then run it, then destroy the instance when you're done. The code by Danyfirex helps get all the args you usually pass in the command line into the AutoIt equivalent of a char** in C/C++. I'll walk through it for beginners so hopefully it can referenced by anyone who needs it in the future. Sorry if it's overly explanatory. Local $aDllArgs[9] = ["gswin32c", _ "-sDEVICE=pdfwrite", _ "-dNOPAUSE", _ "-dBATCH", _ "-dSAFER", _ "-dFirstPage=" & $aParseArgs[3], _ "-dLastPage=" & $aParseArgs[4], _ "-sOutputFile=" & $sDestName & "", _ "" & $sPDFPath & ""] $varList = DllStructCreate("ptr[" & UBound($aDllArgs) & "]") $p_varList = DllStructGetPtr($varList) Local $tData[UBound($aDllArgs)] for $k= 1 to UBound($aDllArgs) $tData[$i-1]=DllStructCreate("char[" & StringLen($aDllArgs[$k-1])+1 & "]") DllStructSetData($varList,1,DllStructGetPtr($tData[$k-1]),$k) ;Debug Pointers ConsoleWrite(DllStructGetData($varList,1,$k) & @CRLF) DllStructSetData($tData[$k-1],1,$aDllArgs[$k-1]) next ;Debug Strings for $i=1 to UBound($aDllArgs) ConsoleWrite(DllStructGetData(DllStructCreate("char[" & StringLen($aDllArgs[$i-1])+1 & "]",DllStructGetData($varList,1,$i)),1) & @CRLF) Next $aDllArgs is my string array for the individual arguments, $varList is the DllStruct of an array of pointers with the size of $aDllArgs. $p_varList stores the pointer to this DllStruct. $tData is created as an array of "char[]" DllStructs, each appropriately sized for the respective string in $aDllArgs. This converts the strings into char arrays for use in the C-code DLL. The corresponding $varList index ($k) then gets the pointer to this new char array, and finally $tData[$k-1] is set to the value of the string. After all this, you can finally call the code to create and work with the instances of gsdll32.dll. The stdout of the DLL appears in the Console window when the script runs. Note: you don't have to pass the paths to the PDF input and output files in quotes - this is different than when you're using the executable. Initially, I had them in quotes and this didn't work, but you'll see in the above code in this post, I've removed the extra quotes. expandcollapse popupLocal $hDll = DllOpen(@ScriptDir & "\gsdll32.dll") ; Open the DLL Local $hInst Local $dResult = DllCall($hDll, "int", "gsapi_new_instance", "ptr*", Null, "ptr", Null) ; Create a new instance, will return a memory location to the instance in position 1 of the result array $hInst = $dResult[1] ; set $hInst to the pointer returned in gsapi_new_instance If $dResult[0] = 0 Then ; If return code was 0, proceed. ConsoleWrite("trying to print PDF" & @CRLF) ; Debug: checks where we are $dResult = DllCall($hDll, "int", "gsapi_init_with_args", "ptr", $hInst, _ "int", UBound($aDllArgs), _ "ptr", $p_varList) ; pass the pointer to the instance, the number of args, and the pointer to the arg array we made previously If @error Then ; Display the error message. MsgBox($MB_SYSTEMMODAL, "", "Error in DllCall (""gsapi_init_with_args""). @error = " & @error) Exit EndIf If $dResult[0] = 0 Then ; If the return code was 0, proceed $dResult = DllCall($hDll, "int", "gsapi_exit", "ptr", $hInst) ; close the instance as we're now done EndIf DllCall($hDll, "none", "gsapi_delete_instance", "ptr", $hInst) ; delete the instance EndIf If @error Then ; Display the error message. MsgBox($MB_SYSTEMMODAL, "", "Can't find Ghostscript DLL (gsdll32.dll) in " & @CRLF & @ScriptDir) ; probably not needed at this point Exit EndIf DllClose($hDll) ; close the DLL in AutoIt ConsoleWrite("closed DLL" & @CRLF) ; Debug: checks where we are 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