Java は JNA を通じて DLL ダイナミック ライブラリ デモを呼び出し、対応する JAR ファイルを生成します。詳細なチュートリアル

Java は JNA を通じて動的ライブラリを呼び出します

  デモ プログラムを作成し、JNA jar パッケージをインポートして JNA を使用して zpl ダイナミック ライブラリを呼び出し、zpl プリンタのポートのオープン、ポートのクローズ、テキスト、バーコード、および QR コードの印刷の機能を完了します。

1: Jna jar パッケージをダウンロードし、jar パッケージ ファイルをプロジェクトにインポートします

  mvn ウェアハウスから対応するバージョンの jar パッケージ ファイルをダウンロードすることにより、このプロジェクトは 5.5.0 jar パッケージをダウンロードし、その jar パッケージをプロジェクト ディレクトリに配置します。jar パッケージの場所に注意することが非常に重要です。保存されています!最初は、jar パッケージをルート ディレクトリに配置するだけでしたが、プロジェクトの後半で jna ライブラリ内のクラスを呼び出すときに NOCLASSFOUND 例外が発生し、長い間悩まされました。そのため、jar パッケージを保存してインポートすることが重要です標準化された方法でプロジェクトに組み込まれます。
  まず、プロジェクトのルート ディレクトリに新しい lib ファイルを作成し、jar パッケージを lib フォルダーに保存します。
ここに画像の説明を挿入します
  jar パッケージをビルド パスに追加します。使用する jar パッケージを右クリックし、「ビルド パス」->「ビルド パスに追加」を選択します。
ここに画像の説明を挿入します   この時点で、プロジェクト ディレクトリ内に追加の参照ライブラリ ディレクトリが存在し、このディレクトリ内に先ほど追加した jar パッケージが存在するため、jar パッケージが実際にプロジェクトに追加されます。
ここに画像の説明を挿入します

2:インターフェースクラスの書き込み

  JNA を通じて DLL ダイナミック ライブラリを呼び出す場合は、DLL ダイナミック ライブラリのメソッドをエクスポートするための新しいインターフェイス クラスを作成する必要があります。
  まず、JNA パッケージに一連のクラスをインポートして DLL ダイナミック ライブラリをロードし、ダイナミック ライブラリ内の java 関数と c 関数メソッドの変換と、対応する仮パラメータ メンバーの型マッピングを完了します。 Java マッピングを次の図に示します。
![ここに画像の説明を挿入](https://img-blog.csdnimg.cn/41e50027459f4b929be07faa67a741da.pngここに画像の説明を挿入します

  上記の Java メソッドはすべて、Java プログラムがメソッドを呼び出せるように、dll ライブラリで使用する必要がある関数を対応する Java 関数メソッドに変換およびマップすることに注意してください。対応するダイナミック ライブラリのみがあり、ソース コードがなく、ダイナミック ライブラリ内のメソッドがわからない場合は、次の方法を使用して DLL ダイナミック ライブラリ内のメソッドを表示できます。
ここに画像の説明を挿入します

  以下の図は、対応する C 関数パラメータのデータ型と Java 仮パラメータのデータ型の変換表です。
ここに画像の説明を挿入します

   上記の実装により、dll ダイナミック ライブラリの呼び出しと、対応する dll ライブラリ関数の Java メソッドへの変換を完了できます。

ダイナミック ライブラリ関数の呼び出しを実装するデモ プログラムを作成する

  これには、Java コントロール クラスを呼び出して GUI インターフェイスの描画を完了する必要があります。具体的なコードは次のとおりです。関数呼び出しは、上記のインターフェースクラスをインポートし、インターフェースクラス内のインスタンスメンバーのメソッドを呼び出すことで実装できます。
ここに画像の説明を挿入します
   DLL ダイナミック ライブラリ関数を呼び出すときは、パラメータの置き換えにエラーがないか注意する必要があります。これを注意深く確認しないと、後で Java 経由で呼び出すときに多くの問題が発生します。後でコードが増えます トラブルシューティングが難しいので、c -> java マッピング表を参照する際はよく確認する必要があります まだ触れていないデータ型マッピングもいくつかあります 具体的なダイナミック ライブラリについてまとめておきます機会があれば、後でデータ型の置換を呼び出してください。

特定のプロジェクトで発生した問題:
    テキストを印刷するために print 関数を呼び出したときに、呼び出しは成功したがプリンターで印刷されなかったことが判明し、その後、印刷の前後にラベル関数を追加する必要があることが判明しました通常の印刷を開始する前に開始ラベルと終了ラベルを設定する機能。
   テキストやバーコードの印刷時にエンコード形式に問題が発生し、印刷データが文字化けする問題が発生しましたが、確認したところ、入力データ型をWStringに変更する必要があり、変更後は正常に印刷できました。

package PrinterSdk;
import com.sun.jna.WString;
import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.UnsupportedEncodingException;
import PrinterSdk.DllUse;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JTextField;
import com.sun.jna.ptr.IntByReference;
public class PrinterDemo {
    
    
    private JFrame frame;
    private JTextField barcode_data;
    private JTextField qrcode_data;
    private JTextField Text;
    private JButton PrBar_btn;
    private JButton PrQr_btn;
    private JButton PrTx_btn;
    private JButton openPort_btn;
    private JButton closePort_btn;
    
    private  int port;
    
    public PrinterDemo()
    {
    
    
        initialize();
    }
    
    private void initialize()
    {
    
    
        frame=new JFrame();
        frame.setBounds(100, 100, 700, 550);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.getContentPane().setLayout(null);
        frame.setTitle("PrinterDemo");
        
        PrTx_btn=new JButton("打印文本");
        PrTx_btn.addActionListener(new ActionListener() {
    
    
            @Override
            public void actionPerformed(ActionEvent e) {
    
    
                // TODO Auto-generated method stub
                try {
    
    
//                    IntByReference i=new IntByReference(0);
//                    int o1=DllUse.instanceDll.OpenPortEx(0, i, 9600, 0);
                    WString data = new WString(Text.getText().toString());//.getBytes("gb18030");
//                    int s=DllUse.instanceDll.StartFormat_ZPL(100,100,10000,100);
                    int o=DllUse.instanceDll.StartData_ZPL(2000, 2000);
//                    DllUse.instanceDll.SetDefaultFont_ZPL(o1, "D".getBytes("gb18030"), 9, 5);
//                    DllUse.instanceDll.SetDataFont_ZPL("C".getBytes("gb18030"), 10000, 10000, "N".getBytes("gb18030"));
//                    DllUse.instanceDll.DataOrientation_ZPL("N".getBytes("gb18030"));
                    String data1="no.1234567";
    //                byte[] data2=data1.getBytes("gb18030");
                    int s=DllUse.instanceDll.StartFormat_ZPL(200,200,40039,40039);
                    int i1=DllUse.instanceDll.PrintData_ZPL(data);
                    DllUse.instanceDll.EndFormat_ZPL(port);
                    System.out.println("文本:"+i1+" "+s);
//                    int status=DllUse.instanceDll.GetPrintStatues_USB(0);
//                    System.out.println("打印机状态:"+status);
                } catch (Exception e1) {
    
    
                    // TODO Auto-generated catch block
                    e1.printStackTrace();
                }
            }
        });
        PrTx_btn.setBounds(500, 100, 100, 80);
        frame.getContentPane().add(PrTx_btn);
        
        PrBar_btn=new JButton("打印条码");
        PrBar_btn.addActionListener(new ActionListener() {
    
    
            @Override
            public void actionPerformed(ActionEvent e) {
    
    
                // TODO Auto-generated method stub
                try {
    
    
//                    IntByReference i1=new IntByReference(0);
//                    int o1=DllUse.instanceDll.OpenPortEx(0, i1, 9600, 0);
                    DllUse.instanceDll.DataOrientation_ZPL("N".getBytes("gb18030"));
                    WString data = new WString(barcode_data.getText().toString());
                    WString data1 = new WString("Y");
//                    byte[] data=barcode_data.getText().getBytes("gb18030");
//                    CodeType type=CodeType.CODE_39;
//                    System.out.println(type);
                    int s1=DllUse.instanceDll.StartFormat_ZPL(200,200,40039,10000);
                    int i=DllUse.instanceDll.BarCode_ZPL(data,2, 100, data1);
                    DllUse.instanceDll.EndFormat_ZPL(port);
                    System.out.println("条码:"+i);
                } catch (UnsupportedEncodingException e1) {
    
    
                    // TODO Auto-generated catch block
                    e1.printStackTrace();
                }
                
            }
        });
        PrBar_btn.setBounds(500, 200, 100, 80);
        frame.getContentPane().add(PrBar_btn);
        
        PrQr_btn=new JButton("打印二维码");
        PrQr_btn.addActionListener(new ActionListener() {
    
    
            @Override
            public void actionPerformed(ActionEvent e) {
    
    
                // TODO Auto-generated method stub
                try {
    
    
//                    IntByReference i1=new IntByReference(0);
//                    int o1=DllUse.instanceDll.OpenPortEx(0, i1, 9600, 0);
//                    int s1=DllUse.instanceDll.StartFormat_ZPL(10,10,100,100);
                    DllUse.instanceDll.DataOrientation_ZPL("N".getBytes("gb18030"));
                    WString data = new WString(qrcode_data.getText().toString());
//                    byte[] data=qrcode_data.getText().getBytes("gb18030");
                    int s=DllUse.instanceDll.StartFormat_ZPL(200,200,40039,10000);
                    int i=DllUse.instanceDll.QRCode_ZPL(data, "M".getBytes("gb18030"), 2, 8);
                    System.out.println("二维码:"+i+" "+s);
                    DllUse.instanceDll.EndFormat_ZPL(port);
                } catch (UnsupportedEncodingException e1) {
    
    
                    // TODO Auto-generated catch block
                    e1.printStackTrace();
                }
            }
        });
        PrQr_btn.setBounds(500,300,100,80);
        frame.getContentPane().add(PrQr_btn);
        
        openPort_btn=new JButton("open port");
        openPort_btn.addActionListener(new ActionListener() {
    
        
            @Override
            public void actionPerformed(ActionEvent e) {
    
    
                // TODO Auto-generated method stub
                IntByReference i=new IntByReference(0);
                port=DllUse.instanceDll.OpenPortEx(0, i, 9600, 0);
                System.out.println("打开端口:"+port);
            }
        });
        openPort_btn.setBounds(100, 170, 100, 40);
        frame.getContentPane().add(openPort_btn);
        
        closePort_btn=new JButton("close port");
        closePort_btn.addActionListener(new ActionListener() {
    
    
            @Override
            public void actionPerformed(ActionEvent e) {
    
    
                // TODO Auto-generated method stub
                DllUse.instanceDll.ClosePort(port);
            }
        });
        closePort_btn.setBounds(100, 270, 100, 40);
        frame.getContentPane().add(closePort_btn);
        
        Text=new JTextField();
        Text.setBounds(300,120,150,40);
        frame.getContentPane().add(Text);
        Text.setColumns(10);
        
        barcode_data=new JTextField();
        barcode_data.setBounds(300,220,150,40);
        frame.getContentPane().add(barcode_data);
        barcode_data.setColumns(10);
        
        qrcode_data=new JTextField();
        qrcode_data.setBounds(300,320,150,40);
        frame.getContentPane().add(qrcode_data);
        qrcode_data.setColumns(10);
    }
    
    public static void main(String[] args) {
    
    
            PrinterDemo window=new PrinterDemo();
            window.frame.setVisible(true);
    }
}

ここに画像の説明を挿入します
  javaDemo プログラムは正常に実行され、対応する動的ライブラリは正常に呼び出されました。

Javaプログラムをjarファイルにパッケージ化する

方法 1:
プロジェクトのルート ディレクトリに新しい MANIFEST.MF ファイルを作成します。
ここに画像の説明を挿入します
ファイルの内容は次のとおりです:
ここに画像の説明を挿入します
  MAIN-CLASSK の先頭にスペースが必要で、メイン メソッドが配置されているメイン クラスの絶対名を書き込みます、最後に Enter キーを押して 4 行目を空のままにします。
  プロジェクト ファイルをクリックしてエクスポートを選択し、jar と入力して、JAR ファイルを選択します。
ここに画像の説明を挿入します
  エクスポートする Java プログラムとサードパーティのパッケージを選択し、エクスポートする jar パッケージの場所と jar パッケージの名前を [JAR ファイル] フィールドで選択します。
ここに画像の説明を挿入します

  • 生成されたクラス ファイルとリソースのエクスポートとは、生成された .class ファイルとその他のリソース ファイルのみをエクスポートすることを意味します。
  • チェックしたプロジェクトのすべての出力フォルダーをエクスポートすると、選択したプロジェクトのすべてのフォルダーがエクスポートされます。
  • Java ソース ファイルとリソースのエクスポートは、エクスポートされた jar パッケージにソース コード *.java が含まれることを意味します。ソース コードを漏洩したくない場合は、このオプションを選択しないでください。
  • チェックしたプロジェクトのリファクタリングのエクスポートには、いくつかのリファクタリング情報ファイルが含まれます


  次に、作成した MANIFEST ファイルを選択し、「完了」をクリックします。
ここに画像の説明を挿入します
方法 2:
実行可能な jar のエクスポートを選択する
ここに画像の説明を挿入します
ここに画像の説明を挿入します
ライブラリ処理部分の説明は次のとおりです。

(1)生成されたJARに必要なライブラリを抽出します。
すべてのインポート JAR を逆アセンブルし、JAR の各ディレクトリ (例: net/org/xxx.class) に含めます。

(2)生成されたJARに必要なライブラリをパッケージ化します。
すべてのインポート JAR を JAR のルート ディレクトリにパッケージ化します。

(3)生成されたJARの隣のサブフォルダーに必要なライブラリをコピーします。
すべてのインポート JAR を JAR の外側の別のフォルダーに配置します。

上記の 2 つの方法により、Java プログラムを jar ファイルにパッケージ化し、端末から jar ファイルを呼び出してプログラムを実行できます。

おすすめ

転載: blog.csdn.net/ccjjjjdff/article/details/129561807