免费视频淫片aa毛片_日韩高清在线亚洲专区vr_日韩大片免费观看视频播放_亚洲欧美国产精品完整版

打開APP
userphoto
未登錄

開通VIP,暢享免費電子書等14項超值服

開通VIP
How to Package JNI Shared Library into Jar File | Dynamsoft Developers

2018 年 9 月 25 日

本文不是關于如何創(chuàng)建調用 C/C++ API 的 Java 本機方法。它旨在幫助開發(fā)人員構建一個包含 JNI 共享庫的 jar 包,使用Dynamsoft Barcode Reader制作,適用于Windows、LinuxmacOS從頭開始??。我將演示如何使用CMake創(chuàng)建 JNI 共享庫,以及如何使用EclipseMaven將類文件和共享庫打包成 jar 文件。

如何將 Maven 與 Dynamsoft 條碼閱讀器一起使用

Dynamsoft 提供了完整的 Java 開發(fā)包。您可以將它與 Maven 一起使用,如下所示:

<repositories>
    <repository>
      <id>dbr</id>
      <url>https://download.dynamsoft.com/maven/dbr/jar</url>
    </repository>
  </repositories>
<dependencies>
    <dependency>
      <groupId>com.dynamsoft</groupId>
      <artifactId>dbr</artifactId>
      <version>6.2</version>
    </dependency>
  </dependencies>

如果你對如何一步步構建這樣的 jar 包不感興趣,可以忽略以下段落。

如何在 Java 中定義本機方法

在 Eclipse 中創(chuàng)建一個新的 Maven 項目。

創(chuàng)建一個 Java 類NativeBarcodeReader.java

public class NativeBarcodeReader {
	
	private long nativePtr = 0;

	static {
		if (System.getProperty("java.vm.vendor").contains("Android")) {
			System.loadLibrary("dbr");
		} else {
			try {
				if (NativeLoader.load()) {
					System.out.println("Successfully loaded Dynamsoft Barcode Reader.");
				}
			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}
	
	public NativeBarcodeReader() {
		nativePtr = nativeCreateInstance();
	}
	
	public void destroyInstance() {
		if (nativePtr != 0)
			nativeDestroyInstance(nativePtr);
	}
	
	public void setLicense(String license) {
		nativeInitLicense(nativePtr, license);
	}
	
	public void decodeFile(String fileName) {
		nativeDecodeFile(nativePtr, fileName);
	}

	private native int nativeInitLicense(long nativePtr, String license);
	
	private native long nativeCreateInstance();
	
	private native void nativeDestroyInstance(long nativePtr);
	
	private native void nativeDecodeFile(long nativePtr, String fileName);
}

注意:如果使用System.load() 方法,則必須在加載 JNI 共享庫之前加載所有依賴項。

Eclipse 會自動將源代碼編譯成一個類文件。使用javah從jni文件夾中的類生成 C 頭NativeBarcodeReader.h 。

mkdir jni
cd jni
javah -cp ..\target\classes -o NativeBarcodeReader.h com.dynamsoft.barcode.NativeBarcodeReader

創(chuàng)建對應的NativeBarcodeReader.cxx文件:

#include "NativeBarcodeReader.h"
#include "DynamsoftBarcodeReader.h"

#ifdef __cplusplus
extern "C"
{
#endif

    /*
    * Class:     com_dynamsoft_barcode_NativeBarcodeReader
    * Method:    nativeInitLicense
    * Signature: (JLjava/lang/String;)I
    */
    JNIEXPORT jint JNICALL Java_com_dynamsoft_barcode_NativeBarcodeReader_nativeInitLicense(JNIEnv *env, jobject, jlong hBarcode, jstring license)
    {
        const char *pszLicense = env->GetStringUTFChars(license, NULL);

        if (hBarcode)
        {
            DBR_InitLicense((void *)hBarcode, pszLicense);
        }

        env->ReleaseStringUTFChars(license, pszLicense);
        return 0;
    }

    /*
    * Class:     com_dynamsoft_barcode_NativeBarcodeReader
    * Method:    nativeCreateInstance
    * Signature: ()J
    */
    JNIEXPORT jlong JNICALL Java_com_dynamsoft_barcode_NativeBarcodeReader_nativeCreateInstance(JNIEnv *, jobject)
    {
        return (jlong)DBR_CreateInstance();
    }

    /*
    * Class:     com_dynamsoft_barcode_NativeBarcodeReader
    * Method:    nativeDestroyInstance
    * Signature: (J)V
    */
    JNIEXPORT void JNICALL Java_com_dynamsoft_barcode_NativeBarcodeReader_nativeDestroyInstance(JNIEnv *, jobject, jlong hBarcode)
    {
        if (hBarcode)
        {
            DBR_DestroyInstance((void *)hBarcode);
        }
    }

    /*
    * Class:     com_dynamsoft_barcode_NativeBarcodeReader
    * Method:    nativeDecodeFile
    * Signature: (JLjava/lang/String;)V
    */
    JNIEXPORT void JNICALL Java_com_dynamsoft_barcode_NativeBarcodeReader_nativeDecodeFile(JNIEnv *env, jobject, jlong ptr, jstring fileName)
    {
        if (ptr)
        {
            void *hBarcode = (void *)ptr;
            const char *pszFileName = env->GetStringUTFChars(fileName, NULL);

            DBR_DecodeFile(hBarcode, pszFileName, "");

            STextResultArray *paryResult = NULL;
            DBR_GetAllTextResults(hBarcode, &paryResult);

            int count = paryResult->nResultsCount;
            int i = 0;
            for (; i < count; i++)
            {
                printf("Index: %d, Type: %s, Value: %s\n", i, paryResult->ppResults[i]->pszBarcodeFormatString, paryResult->ppResults[i]->pszBarcodeText); // Add results to list
            }

            // Release memory
            DBR_FreeTextResults(&paryResult);

            env->ReleaseStringUTFChars(fileName, pszFileName);
        }
    }

#ifdef __cplusplus
}
#endif

這里的代碼非常簡單。如果您愿意,可以添加更多實現(xiàn)。

SDK

下載 適用于 Windows、Linux 和 macOS 的 Dynamsoft Barcode Reader。

將依賴于操作系統(tǒng)的共享庫復制到 jni/platforms 文件夾。

  • jni/平臺/贏
    • DBRx64.lib
    • DynamicPdfx64.dll
    • DynamsoftBarcodeReaderx64.dll
    • vcomp110.dll
  • jni/平臺/linux
    • libDynamicPdf.so
    • libDynamsoftBarcodeReader.so
  • jni/平臺/macos
    • libDynamsoftBarcodeReader.dylib

如何使用 CMake 構建 JNI 共享庫

創(chuàng)建一個CMakeLists.txt文件。

定義 Java 包含和 lib 目錄:

if (CMAKE_HOST_WIN32)
    set(WINDOWS 1)
    set(JAVA_INCLUDE "C:/Program Files/Java/jdk1.8.0_181/include")
    set(JAVA_INCLUDE_OS "C:/Program Files/Java/jdk1.8.0_181/include/win32")
elseif(CMAKE_HOST_APPLE)
    set(MACOS 1)
    set(JAVA_INCLUDE "/System/Library/Frameworks/JavaVM.framework/Headers")
    set(JAVA_INCLUDE_OS "")
elseif(CMAKE_HOST_UNIX)
    set(LINUX 1)
    set(JAVA_INCLUDE "/usr/lib/jvm/java-1.8.0-openjdk-amd64/include/")
    set(JAVA_INCLUDE_OS "/usr/lib/jvm/java-1.8.0-openjdk-amd64/include/linux")
endif()

if(WINDOWS)
    link_directories("${PROJECT_SOURCE_DIR}/platforms/win" "C:/Program Files/Java/jdk1.8.0_181/lib") 
    include_directories("${PROJECT_BINARY_DIR}" "${PROJECT_SOURCE_DIR}/include" "${PROJECT_SOURCE_DIR}" "${JAVA_INCLUDE}" "${JAVA_INCLUDE_OS}")
elseif(LINUX)
    link_directories("${PROJECT_SOURCE_DIR}/platforms/linux") 
    include_directories("${PROJECT_BINARY_DIR}" "${PROJECT_SOURCE_DIR}/include" "${PROJECT_SOURCE_DIR}" "${JAVA_INCLUDE}" "${JAVA_INCLUDE_OS}")
elseif(MACOS)
    link_directories("${PROJECT_SOURCE_DIR}/platforms/macos") 
    include_directories("${PROJECT_BINARY_DIR}" "${PROJECT_SOURCE_DIR}/include" "${PROJECT_SOURCE_DIR}" "${JAVA_INCLUDE}")
endif()

鏈接 Dynamsoft Barcode Reader 以生成不同平臺的 JNI 共享庫。對于 macOS ,將文件后綴從 dylib 重命名為jnilib

add_library(dbr SHARED NativeBarcodeReader.cxx)
if(MACOS)
    set_target_properties(dbr PROPERTIES SUFFIX ".jnilib")
endif()
if(WINDOWS)
    if(CMAKE_CL_64)
        target_link_libraries (dbr "DBRx64")
    else()
        target_link_libraries (dbr "DBRx86")
    endif()
else()
    target_link_libraries (dbr "DynamsoftBarcodeReader")
endif()

安裝庫:

set(CMAKE_INSTALL_PREFIX "${PROJECT_SOURCE_DIR}/../src/main/")
set(ECLIPSE_PATH "java/com/dynamsoft/barcode/native")
set(MAVEN_PATH "resources/com/dynamsoft/barcode/native")
if(WINDOWS)
    install (DIRECTORY "${PROJECT_SOURCE_DIR}/platforms/win" DESTINATION "${CMAKE_INSTALL_PREFIX}${ECLIPSE_PATH}")
    install (DIRECTORY "${PROJECT_SOURCE_DIR}/platforms/win" DESTINATION "${CMAKE_INSTALL_PREFIX}${MAVEN_PATH}")
    install (TARGETS dbr DESTINATION "${CMAKE_INSTALL_PREFIX}${ECLIPSE_PATH}/win")
    install (TARGETS dbr DESTINATION "${CMAKE_INSTALL_PREFIX}${MAVEN_PATH}/win")
elseif(LINUX)
    install (DIRECTORY "${PROJECT_SOURCE_DIR}/platforms/linux" DESTINATION "${CMAKE_INSTALL_PREFIX}${ECLIPSE_PATH}")
    install (DIRECTORY "${PROJECT_SOURCE_DIR}/platforms/linux" DESTINATION "${CMAKE_INSTALL_PREFIX}${MAVEN_PATH}")
    install (TARGETS dbr DESTINATION "${CMAKE_INSTALL_PREFIX}${ECLIPSE_PATH}/linux")
    install (TARGETS dbr DESTINATION "${CMAKE_INSTALL_PREFIX}${MAVEN_PATH}/linux")
elseif(MACOS)
    install (DIRECTORY "${PROJECT_SOURCE_DIR}/platforms/macos" DESTINATION "${CMAKE_INSTALL_PREFIX}${ECLIPSE_PATH}")
    install (DIRECTORY "${PROJECT_SOURCE_DIR}/platforms/macos" DESTINATION "${CMAKE_INSTALL_PREFIX}${MAVEN_PATH}")
    install (TARGETS dbr DESTINATION "${CMAKE_INSTALL_PREFIX}${ECLIPSE_PATH}/macos")
    install (TARGETS dbr DESTINATION "${CMAKE_INSTALL_PREFIX}${MAVEN_PATH}/macos")
endif()

ECLIPSE_PATH  用于 Eclipse 導出 jar 文件,而  MAVEN_PATH用于Maven 導出 jar 文件。

構建 JNI 共享庫。

視窗

例如,Visual Studio 2017

mkdir build
cd build
cmake -G"Visual Studio 15 2017 Win64" .. 
cmake --build . --config Release --target install

Linux 和 macOS

mkdir build
cd build
cmake .. 
cmake --build . --config Release --target install

如何將原生庫打包成 Jar 文件

編輯 pom.xml 文件,添加共享庫目錄:

<project xmlns="http://maven.apache.org/POM/4.0.0" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.dynamsoft</groupId>
    <artifactId>barcode</artifactId>
    <version>1.0.0</version>
    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>
    <build>
        <resources>
            <resource>
                <directory>src/main/resources</directory>
                <excludes>
                    <exclude>**/*.md</exclude>
                    <exclude>**/*.h</exclude>
                    <exclude>**/*.lib</exclude>
                </excludes>
            </resource>
        </resources>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>2.5.1</version>
                <configuration>
                    <source>1.7</source>
                    <target>1.7</target>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

在目標文件夾中生成jar文件:

mvn package

或者,您可以使用 Eclipse 導出 jar 文件。

這是生成的jar文件。

如何從 jar 文件中加載 JNI 共享庫

列出所有依賴庫文件:

String[] filenames = null;
		if (Utils.isWindows()) {
			filenames = new String[] {"vcomp110.dll", "DynamicPdfx64.dll", "DynamsoftBarcodeReaderx64.dll", "dbr.dll"};
		}
		else if (Utils.isLinux()) {
			filenames = new String[] {"libDynamicPdf.so", "libDynamsoftBarcodeReader.so", "libdbr.so"};
		}
		else if (Utils.isMac()) {
			filenames = new String[] {"libDynamsoftBarcodeReader.dylib", "libdbr.jnilib"};
		}
		
		boolean ret = true;
		
		for (String file : filenames) {
			ret &= extractAndLoadLibraryFile(dbrNativeLibraryPath, file, tempFolder);
		}

將共享庫提取到臨時文件夾:

private static boolean extractAndLoadLibraryFile(String libFolderForCurrentOS, String libraryFileName,
			String targetFolder) {
		String nativeLibraryFilePath = libFolderForCurrentOS + "/" + libraryFileName;

		String extractedLibFileName = libraryFileName;
		File extractedLibFile = new File(targetFolder, extractedLibFileName);

		try {
			if (extractedLibFile.exists()) {
				// test md5sum value
				String md5sum1 = md5sum(NativeBarcodeReader.class.getResourceAsStream(nativeLibraryFilePath));
				String md5sum2 = md5sum(new FileInputStream(extractedLibFile));

				if (md5sum1.equals(md5sum2)) {
					return loadNativeLibrary(targetFolder, extractedLibFileName);
				} else {
					// remove old native library file
					boolean deletionSucceeded = extractedLibFile.delete();
					if (!deletionSucceeded) {
						throw new IOException(
								"failed to remove existing native library file: " + extractedLibFile.getAbsolutePath());
					}
				}
			}

			// Extract file into the current directory
			InputStream reader = NativeBarcodeReader.class.getResourceAsStream(nativeLibraryFilePath);
			FileOutputStream writer = new FileOutputStream(extractedLibFile);
			byte[] buffer = new byte[1024];
			int bytesRead = 0;
			while ((bytesRead = reader.read(buffer)) != -1) {
				writer.write(buffer, 0, bytesRead);
			}

			writer.close();
			reader.close();

			if (!System.getProperty("os.name").contains("Windows")) {
				try {
					Runtime.getRuntime().exec(new String[] { "chmod", "755", extractedLibFile.getAbsolutePath() })
							.waitFor();
				} catch (Throwable e) {
				}
			}

			return loadNativeLibrary(targetFolder, extractedLibFileName);
		} catch (IOException e) {
			System.err.println(e.getMessage());
			return false;
		}

	}

使用絕對路徑加載庫:

private static synchronized boolean loadNativeLibrary(String path, String name) {
		File libPath = new File(path, name);
		if (libPath.exists()) {
			try {
				System.load(new File(path, name).getAbsolutePath());
				return true;
			} catch (UnsatisfiedLinkError e) {
				System.err.println(e);
				return false;
			}

		} else
			return false;
	}

運行測試:

java -cp ./target/barcode-1.0.0.jar com.dynamsoft.barcode.Test

參考

源代碼

https://github.com/dynamsoft-dbr/java-jni-barcode

本站僅提供存儲服務,所有內容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權內容,請點擊舉報。
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
Android筆記之使用CMake進行JNI開發(fā)(Android Studio)
How to fix an UnsatisfiedLinkError (Can't find dependent libraries) in a JNI project
cmake 導入鏈接庫
cmake之 第三方庫始終報錯 /usr/bin/ld: cannot find
如何在Linux中使用WASI SDK將ZXing C ++構建為Wasm
FFMPEG移植到Android(ubuntu環(huán)境下)
更多類似文章 >>
生活服務
分享 收藏 導長圖 關注 下載文章
綁定賬號成功
后續(xù)可登錄賬號暢享VIP特權!
如果VIP功能使用有故障,
可點擊這里聯(lián)系客服!

聯(lián)系客服