[gs-devel] Problem with callback functions in API (without header
file because otherwise >12kb)
cpoisel at exago.de
cpoisel at exago.de
Fri Jun 18 02:41:54 PDT 2004
Hello
At the moment i'm writing a Document Management Solution that should
integrate with an existing VB6 Application. As I don't like to do work
twice I decided to write this new Software as a servlet based on Java &
Tomcat so that it can be used across multiple platforms. To make it
possible to import data that is output on a printer I started to write a
virtual network printer that should be able to accept Postscript
printjobs and convert it to several formats (the most important one is
PDF). I decided to use Ghostscript as the backend for file conversion
and wrote an interface class and shared library to get the input from a
java DataInputStream into Ghostscript and back into a DataOutputStream.
I use the gsapi_set_stdio call to redirect stdin, stdout and stderr.
Everything works fine now except one thing: I don't get the PDF output
redirected to my stdout function and so i don't get it back into java.
The redirection routines work (I was able to write the following to
stdout and stderr function depending on the parameters chosen in
gsapi_init_with_args)
AFPL Ghostscript 8.14 (2004-02-20)
Copyright (C) 2004 artofcode LLC, Benicia, CA. All rights reserved.
This software comes with NO WARRANTY: see the file PUBLIC for details.
Loading NimbusRomNo9L-Regu font from C:\gs\fonts/n021003l.pfb... 2368360
978610 1557192 268445 3 done.
At the moment I use the following parameters (but i also have already
used every spelling possible for redirecting stdio )
-Sstdout=%stderr
-dNOPAUSE
-dBATCH
-sOutputFile=%stdout
-sDEVICE=pdfwrite
-
The result is: AFPL Ghostscript 8.14 ... is written to a file connected
to stderr via JAVA that's correct
The file connected to stdout via JAVA is empty (0 bytes
long) that's where i expected the output file
The pdf output is written to the console I started the
application from.
I'm able to create a PDF output-file with the following command:
java gsAPIwrap >out.pdf
I have absolutely no idea what to do to get the PDF output redirected to
my stdout redirection function.
========================================================================
=====================================================
CODE:
Not yet commented, sorry
jgsAPIdll.c
------------------------------------------------------------------------
-----------------------------------------------------
/* Include JNI Header File */
#include "gsAPIwrap.h"
/* Include System Header Files */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/* Include Ghostscript Header Files and neccessary System Header Files
*/
#if defined(_WIN32) && !defined(_Windows)
# define _Windows
#endif
#ifdef _Windows
# include <windows.h>
# define GSDLLEXPORT __declspec(dllimport)
#endif
#include <iapi.h>
#include <ierrors.h>
int status = 0;
#define _status_instance_defined 1
#define _status_stdio_redirect 2
#define _define_status(mask) status=status&mask
#define _undefine_status(mask) status=status&~mask
#define _if_defined(mask) if((status & mask)>0)
#define _define_instance status=_define_status(_status_instance_defined)
#define _redirect_stdio status=_define_status(_status_stdio_redirect)
#define _undefine_instance
status=_undefine_status(_status_instance_defined)
#define _unredirect_stdio
status=_undefine_status(_status_stdio_redirect)
#define _if_instance_defined _if_defined(_status_instance_defined)
#define _if_stdio_redirected _if_defined(_status_stdio_redirect)
gs_main_instance *minst;
JNIEnv *lenv;
jobject lobj;
jmethodID getMethodID(JNIEnv *env, jobject obj, char *methodname, char
*methodsignature) {
jclass cls;
jmethodID mid;
cls = (*env)->GetObjectClass(env, obj);
mid = (*env)->GetMethodID(env, cls, methodname,
methodsignature);
return mid;
}
static int GSDLLCALL gsdll_stdin(void *instance, char *buf, int len) {
jmethodID mid;
jbyteArray inarr;
jsize sz;
inarr = (*lenv)->NewByteArray(lenv,len);
mid = getMethodID(lenv, lobj, "gsSTDIN", "([BI)I");
sz = (*lenv)->CallIntMethod(lenv, lobj, mid, inarr, len);
(*lenv)->GetByteArrayRegion(lenv,inarr,0,sz,buf);
return sz;
}
static int GSDLLCALL gsdll_stdout(void *instance, const char *str, int
len) {
jmethodID mid;
jbyteArray outarr;
jsize sz;
outarr = (*lenv)->NewByteArray(lenv,len);
(*lenv)->SetByteArrayRegion(lenv,outarr,0,len,(byte*)str);
mid = getMethodID(lenv, lobj, "gsSTDOUT", "([BI)I");
sz = (*lenv)->CallIntMethod(lenv, lobj, mid, outarr, len);
printf("stdout called: %s\n", str);
return sz;
}
static int GSDLLCALL gsdll_stderr(void *instance, const char *str, int
len) {
jmethodID mid;
jbyteArray errarr;
jsize sz;
errarr = (*lenv)->NewByteArray(lenv,len);
(*lenv)->SetByteArrayRegion(lenv,errarr,0,len,(byte*)str);
mid = getMethodID(lenv, lobj, "gsSTDERR", "([BI)I");
sz = (*lenv)->CallIntMethod(lenv, lobj, mid, errarr, len);
return sz;
}
JNIEXPORT void JNICALL Java_gsAPIwrap_jgsRevision (JNIEnv *env, jobject
obj) {
jstring product, copyright;
jint revision, revdate;
jmethodID mid;
gsapi_revision_t r;
if (gsapi_revision(&r, sizeof(r))==0) {
product = (*env)->NewStringUTF(env, r.product);
copyright = (*env)->NewStringUTF(env, r.copyright);
revision = r.revision;
revdate = r.revisiondate;
mid = getMethodID(env, obj, "gsInitSuccess",
"(Ljava/lang/String;Ljava/lang/String;II)V");
(*env)->CallVoidMethod(env, obj, mid, product,
copyright, revision, revdate);
}
}
JNIEXPORT void JNICALL Java_gsAPIwrap_jgsNewInstance(JNIEnv *env,
jobject obj) {
/* jmethodID mid;*/
if (gsapi_new_instance(&minst, NULL)<0) {
_define_instance;
}
}
JNIEXPORT void JNICALL Java_gsAPIwrap_jgsDeleteInstance(JNIEnv *env,
jobject obj) {
_if_instance_defined {
_undefine_instance;
gsapi_delete_instance(minst);
}
}
JNIEXPORT void JNICALL Java_gsAPIwrap_jgsSetStdio(JNIEnv *env, jobject
obj) {
_if_stdio_redirected {
(*lenv)->DeleteGlobalRef(lenv,lobj);
_unredirect_stdio;
}
gsapi_set_stdio(minst, gsdll_stdin, gsdll_stdout, gsdll_stderr);
lobj = (*env)->NewGlobalRef(env,obj);
lenv = env;
_redirect_stdio;
}
JNIEXPORT void JNICALL Java_gsAPIwrap_jgsInitWithArgs(JNIEnv *env,
jobject obj) {
jmethodID mid;
jobjectArray joa;
jsize len, pos;
jstring param;
const char *pstr;
char *astr;
char **parr;
mid = getMethodID(env, obj, "getParameters",
"()[Ljava/lang/Object;");
joa = (jarray)(*env)->CallObjectMethod(env, obj, mid);
len = (*env)->GetArrayLength(env,joa);
parr=(char**) calloc(len+1,sizeof(char*));
(char*)*parr = "JAVA 2 Ghostscript Interface";
for (pos=0; pos<len; pos++) {
param =
(jstring)(*env)->GetObjectArrayElement(env,joa,pos);
pstr = (*env)->GetStringUTFChars(env,param,NULL);
astr = strcpy((char*)malloc(strlen(pstr)+1),pstr);
(char*)*(parr+pos+1) = astr;
(*env)->ReleaseStringUTFChars(env,param,pstr);
}
gsapi_init_with_args(minst,len+1,parr);
for (pos=1; pos<len+1; pos++) {
free(*(parr+pos));
}
free(parr);
}
JNIEXPORT void JNICALL Java_gsAPIwrap_jgsExit(JNIEnv *env, jobject obj)
{
gsapi_exit(minst);
}
More information about the gs-devel
mailing list