Access violation when calling the Zebra printer API

1
# A fatal error has been detected by the Java Runtime Environment:
#
#  EXCEPTION_ACCESS_VIOLATION (0xc0000005) at pc=0x5f0c25fe, pid=14780, tid=11168
#
# JRE version: Java(TM) SE Runtime Environment (7.0_80-b15) (build 1.7.0_80-b15)
# Java VM: Java HotSpot(TM) Client VM (24.80-b11 mixed mode, sharing windows-x86 )
# Problematic frame:
# C  [ZBRGraphics.dll+0x25fe]

I keep getting this error when using the Zebra printer DLL in Java program.

public class Tester {
    public static void main(String[] args) {
        ZBRGraphics zGraphics = ZBRGraphics.INSTANCE;

        String text = "Print this";
        byte[] textB = text.getBytes(StandardCharsets.UTF_8);

        String font= "Arial";
        byte[] fontB = text.getBytes(StandardCharsets.UTF_8);

        System.out.println(zGraphics.ZBRGDIDrawText(0, 0, textB, fontB, 12, 1, 0x0FF0000, 0));
    }
}

public interface ZBRGraphics extends Library {
    ZBRGraphics INSTANCE = (ZBRGraphics) Native.loadLibrary("ZBRGraphics", ZBRGraphics.class);

    int ZBRGDIDrawText(int x, int y, byte[] text, byte[] font, int fontSize, int fontStyle, int color, int err);
}

I have the DLL in C:\Windows\System32 and in my 32 bit Java . I'm using a 64 bit machine as my laptop for development.

java
jna
asked on Stack Overflow Jun 20, 2018 by DarthVeder • edited Jun 23, 2018 by cbr

1 Answer

1

If my google-fu skills are any good, you appear to be interfacing with the Zebra printer's API. According to the "ZXP1 & ZXP3 Software Developers Reference Manual" (found here), the Java mapping of the function is incorrect.

This is the actual C function prototype:

int ZBRGDIDrawText(
    int x,
    int y,
    char *text,
    char *font,
    int fontSize,
    int fontStyle,
    int color,
    int *err
)

As you can see, err is not an int, but a pointer to one. Also, since text and font are strings, you can just use a String as the Java type. Additionally, the API docs say that the return value is an int with either 1 for success or 0 for failure, meaning that you can use a boolean for ease of use.

The following Java mapping should be correct:

boolean ZBRGDIDrawText(
    int x,
    int y,
    String text,
    String font,
    int fontSize,
    int fontStyle,
    int color,
    IntByReference err
);

and you might use it like so:

IntByReference returnCode = new IntByReference(0);
boolean success = zGraphics.ZBRGDIDrawText(
    0,
    0,
    "Print this",
    "Arial",
    12,
    1,
    0x0FF0000,
    returnCode
);

if (success) {
    System.out.println("success");
} else {
    System.out.println("ZBRGDIDrawText failed with code " + returnCode.getValue());
}
answered on Stack Overflow Jun 21, 2018 by cbr • edited Jun 23, 2018 by cbr

User contributions licensed under CC BY-SA 3.0