Summary: | gsapi_init_with_args when -sDevice=display on 64 bit ghostscript library | ||
---|---|---|---|
Product: | Ghostscript | Reporter: | Josip Habjan <habjan> |
Component: | Client API | Assignee: | Default assignee <ghostpdl-bugs> |
Status: | RESOLVED INVALID | ||
Severity: | normal | CC: | chris.liddell |
Priority: | P4 | ||
Version: | 9.10 | ||
Hardware: | PC | ||
OS: | Windows 7 | ||
Customer: | Word Size: | --- | |
Attachments: |
Test source code
Simple display device test code |
Description
Josip Habjan
2013-08-29 03:04:24 UTC
I'm not a C# programmer. I'm prepared to look at the problem, and I can at least run a C# app under the debugger. However, I only have the express version of VS 2012 and when I try to load your application it gives me a number of warnings and errors, and then crashes Visual Studio. I doubt that I need the full complexity of your application to investigate this. Can you please instead supply a minimal application to demonstrate the problem. FWIW our own 64-bit executable uses the gsapi_init_with_args routine, so it *does* work under 64-bit Windows. On 64 bit systems the "DisplayHandle" parameter is a string, because these params are integers which are (mostly) 32 bit. You'll need to convert the pointer value into a string, and pass it with "-sDisplayHandle=<string>" See: http://git.ghostscript.com/?p=ghostpdl.git;a=blob;f=gs/devices/gdevdsp.c and search for "DisplayHandle as a string" Its also even documented in API.htm: " -sDisplayHandle=1234 Where "1234" is a string. The API was changed to use a string rather than an integer/long value when support for 64 bit systems arrived. A display "handle" is often a pointer, and since these command line options have to survive being processed by Postscript machinery, and Postscript only permits 32 bit number values, a different representation was required." Thanks Chris Created attachment 10154 [details]
Test source code
Minimal source code for test.
Thank you, i will check, try what you suggested me and let you know. This are my 32 bit arguments: string[] args_x86 = new string[] { "", "-sDEVICE=display", "-dTextAlphaBits=4", "-dGraphicAlphaBits=4", "-dDisplayHandle=0", "-dDisplayResolution=72", "-dDisplayFormat=" + ((int)DISPLAY_FORMAT_COLOR.DISPLAY_COLORS_RGB | (int)DISPLAY_FORMAT_ALPHA.DISPLAY_ALPHA_NONE | (int)DISPLAY_FORMAT_DEPTH.DISPLAY_DEPTH_8 | (int)DISPLAY_FORMAT_ENDIAN.DISPLAY_LITTLEENDIAN | (int)DISPLAY_FORMAT_FIRSTROW.DISPLAY_BOTTOMFIRST).ToString() }; And this are 64 bit: string[] args_x64 = new string[] { "", "-sDEVICE=display", "-dTextAlphaBits=4", "-dGraphicAlphaBits=4", "-sDisplayHandle=0", "-dDisplayResolution=72", "-sDisplayFormat=" + ((int)DISPLAY_FORMAT_COLOR.DISPLAY_COLORS_RGB | (int)DISPLAY_FORMAT_ALPHA.DISPLAY_ALPHA_NONE | (int)DISPLAY_FORMAT_DEPTH.DISPLAY_DEPTH_8 | (int)DISPLAY_FORMAT_ENDIAN.DISPLAY_LITTLEENDIAN | (int)DISPLAY_FORMAT_FIRSTROW.DISPLAY_BOTTOMFIRST).ToString() }; 32 bit works file, 64 returns: Unrecoverable error: typecheck in .putdeviceprops I want display handle to be 0. (In reply to comment #6) > This are my 32 bit arguments: > > string[] args_x86 = new string[] { > "", > "-sDEVICE=display", > "-dTextAlphaBits=4", > "-dGraphicAlphaBits=4", > "-dDisplayHandle=0", > "-dDisplayResolution=72", > "-dDisplayFormat=" + > ((int)DISPLAY_FORMAT_COLOR.DISPLAY_COLORS_RGB | > > (int)DISPLAY_FORMAT_ALPHA.DISPLAY_ALPHA_NONE | > > (int)DISPLAY_FORMAT_DEPTH.DISPLAY_DEPTH_8 | > > (int)DISPLAY_FORMAT_ENDIAN.DISPLAY_LITTLEENDIAN | > > (int)DISPLAY_FORMAT_FIRSTROW.DISPLAY_BOTTOMFIRST).ToString() }; > > And this are 64 bit: > > string[] args_x64 = new string[] { > "", > "-sDEVICE=display", > "-dTextAlphaBits=4", > "-dGraphicAlphaBits=4", > "-sDisplayHandle=0", > "-dDisplayResolution=72", > "-sDisplayFormat=" + > ((int)DISPLAY_FORMAT_COLOR.DISPLAY_COLORS_RGB | > > (int)DISPLAY_FORMAT_ALPHA.DISPLAY_ALPHA_NONE | > > (int)DISPLAY_FORMAT_DEPTH.DISPLAY_DEPTH_8 | > > (int)DISPLAY_FORMAT_ENDIAN.DISPLAY_LITTLEENDIAN | > > (int)DISPLAY_FORMAT_FIRSTROW.DISPLAY_BOTTOMFIRST).ToString() }; > > 32 bit works file, 64 returns: Unrecoverable error: typecheck in > .putdeviceprops > > I want display handle to be 0. Well, 0 is still an integer, not a string..... I *think* you'll need a string containing '0'. I solved the "string" "number" problem. for 64 bit i'm now using -dDisplayFormat and -dDisplayHandle as suggested in API docs. The error i now get is: -15 **** Unable to open the display device, quitting. Chris, the 0 in this case is a string. For instance: "-sDEVICE=display" - value is string "-sDisplayHandle=0" - value is string "-dDisplayHandle=0" - value is integer Well, you can get the Ghostscript source, and you can see where the parameter is being read, so you can debug why it's throwing an error. *Or* you could create a very minimal C app which shows the error, so we can debug it. If it will be easier for you to see my screen, click on this: https://join.me/580-140-202 (it's web broser based screen sharing) I'm not C/C++ developer, can any of you please try if this works on 64 bit version? char **nargv; char arg1[64]; char arg2[64]; char arg3[64]; code = gsapi_new_instance(&minst, NULL); gsapi_set_stdio(minst, gsdll_stdin, gsdll_stdout, gsdll_stderr); code = gsapi_set_display_callback(minst, &display_callback); sprintf(arg1, "-sDEVICE=display"); sprintf(arg2, "-sDisplayHandle=%d", 0); sprintf(arg3, "-dDisplayFormat=%d", DISPLAY_COLORS_RGB | DISPLAY_ALPHA_NONE | DISPLAY_DEPTH_8 | DISPLAY_LITTLEENDIAN | DISPLAY_BOTTOMFIRST); nargv = (char **)malloc((argc + 4) * sizeof(char *)); nargv[0] = argv[0]; nargv[1] = arg1; nargv[2] = arg2; nargv[3] = arg3; memcpy(nargv + 4, argv + 1, argc * sizeof(char *)); argc += 3; code = gsapi_init_with_args(minst, argc, nargv); Thanks, Josip (In reply to comment #11) > I'm not C/C++ developer, can any of you please try if this works on 64 bit > version? That doesn't work on either 32 or 64-bits. This works on both: sprintf(arg1, "-sDEVICE=display"); sprintf(arg2, "-sDisplayHandle=%d", 0); sprintf(arg3, "-dDisplayFormat=%d", DISPLAY_COLORS_RGB | DISPLAY_ALPHA_NONE | DISPLAY_DEPTH_8 | DISPLAY_LITTLEENDIAN | DISPLAY_BOTTOMFIRST); nargc = argc + 3; nargv = (char **)malloc((nargc + 1) * sizeof(char *)); nargv[0] = argv[0]; nargv[1] = arg1; nargv[2] = arg2; nargv[3] = arg3; memcpy(&nargv[4], &argv[1], argc * sizeof(char *)); Created attachment 10157 [details]
Simple display device test code
Yours has a fair amount missing, so I've attached a complete example, which can drop in replacing the existing psi\dwmainc.c source file.
You need to use the 64 bit Visual Studio command prompt, and build with:
nmake -f psi\msvc.mak DEVSTUDIO= BUILD_SYSTEM=64 WIN64=1 MAKEDLL=0
Running gswin64c.exe after that outputs:
GPL Ghostscript GIT PRERELEASE 9.10 (2013-08-14)
Copyright (C) 2013 Artifex Software, Inc. All rights reserved.
This software comes with NO WARRANTY: see the file PUBLIC for details.
code = 0
Which is what I'd expect. So the setting of -sDisplayHandle=0 works as it should. So it would seem something about the C#->C/C++ binding is possibly the culprit. Is it possible the string is being converted to some Unicode variant, rather than being in plain ASCII. Possibly, you could build the GS DLL with the "GS_NO_UTF8=1" setting, thus:
nmake -f psi\msvc.mak DEVSTUDIO= BUILD_SYSTEM=64 WIN64=1 MAKEDLL=0 GS_NO_UTF8=1
again in the VS 64 bit tools command prompt window.
Ken, the sample i posted was the sample from the current API doc. Chris, thanks, you were right. I managed to solve my problem by setting aligning fields to the default packing size for the current platform for the display_device structure callback. 32-bit works with A value of 1 indicates that data alignment occurs on byte boundaries. There are no gaps between fields with a packing value of 1. Default is 0 that indicates that the packing alignment is set to the default for the current platform. Packing values of 2 and higher will cause each field to be aligned on a byte offset relative to the beginning of the structure. Therefore, data fields will start on offsets that are multiples of the requested packing value. Thank you both. |