将 lib 添加到 jni 应用程序的 makefile

Posted

技术标签:

【中文标题】将 lib 添加到 jni 应用程序的 makefile【英文标题】:Add lib to makefile for jni app 【发布时间】:2017-05-06 12:12:46 【问题描述】:

我不明白如何使用 JNI 在 java 中运行 c++ 代码。 我认为makefile中有一些错误,我认为缺少一些lib。

我在 java 类中有这段代码:

private native void getCanny(long mat);
getCanny(mat.getNativeObjAddr());

以及生成的 Mat2Image.h:

/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class Mat2Image */

#ifndef _Included_Mat2Image
#define _Included_Mat2Image
#ifdef __cplusplus
extern "C" 
#endif
/*
 * Class:     Mat2Image
 * Method:    getCanny
 * Signature: (J)V
 */
JNIEXPORT void JNICALL Java_Mat2Image_getCanny
  (JNIEnv *, jobject, jlong);

#ifdef __cplusplus

#endif
#endif

这是我制作的 .cpp:

#include "Mat2Image.h"
#include <iostream>
#include <opencv2/core/core.hpp>
#include <opencv2/imgproc.hpp>


JNIEXPORT void JNICALL Java_Mat2Image_getCanny
   (JNIEnv * env, jobject obj, jlong matr)


       cv::Mat* frame=(cv::Mat*)matr;
            cv::cvtColor(*frame, *frame, CV_BGR2GRAY);
            cv::GaussianBlur(*frame, *frame, cv::Size(7,7), 1.5, 1.5);
            cv::Canny(*frame, *frame, 0, 30, 3);



这是我的makefile:

# Define a variable for classpath
CLASS_PATH = ../bin

# Debug: -g3=compile with extra debugg infos. -ggdbg3=include things like macro defenitions. -O0=turn off optimizations.
DEBUGFLAGS = -g3 -ggdb3 -O0
CFLAGS = $(DEBUGFLAGS)

# Define a virtual path for .class in the bin directory
vpath %.class $(CLASS_PATH)

all : libMat.so

# $@ matches the target, $< matches the first dependancy
libMat.so : libMat.o
    g++ $(CFLAGS) -W -shared -o $@ $<

# $@ matches the target, $< matches the first dependancy
libMat.o : Mat2Image.cpp Mat2Image.h
    g++ $(CFLAGS) -fPIC -I/usr/lib/jvm/jdk1.8.0_111/include -I/usr/lib/jvm/jdk1.8.0_111/include/linux -c $< -o $@

# $* matches the target filename without the extension
# manually this would be: javah -classpath ../bin HelloJNI
HelloJNI.h : Mat2Image.class
    javah -classpath $(CLASS_PATH) $*

clean :
    rm -f Mat2Image.h libMat.o libMat.so

但是当我尝试运行该方法时出现此错误:

/usr/lib/jvm/jdk1.8.0_111/bin/java: symbol lookup error: /home/buzzo/Downloads/helloJni-master/jni/libMat.so: undefined symbol: _ZN2cv8cvtColorERKNS_11_InputArrayERKNS_12_OutputArrayEii

我认为问题是makefile,我该如何编辑它?

【问题讨论】:

没有人可以帮助我吗?请... 【参考方案1】:

您的代码似乎使用了未链接的符号。

我建议将您的共享库与 opencv 链接?

如果您想查看使用 JNI 共享库的示例代码,请查看此处:

https://github.com/mkowsiak/jnicookbook/tree/master/recipes/recipeNo023

在您的情况下,opencv 库似乎不在 LD_LIBRARY_PATH 上。

【讨论】:

太棒了!玩 JNI!【参考方案2】:

我通过修改makefile解决了:

我变了

libMat.so : libMat.o
    g++ $(CFLAGS) -W -shared -o $@ $<

libMat.so : libMat.o
    g++ $(CFLAGS) -W -shared -o $@ $< -lopencv_imgproc

这是最终的生成文件:

# Define a variable for classpath
CLASS_PATH = ../bin
# Debug: -g3=compile with extra debugg infos. -ggdbg3=include things like macro defenitions. -O0=turn off optimizations.
DEBUGFLAGS = -g3 -ggdb3 -O0
CFLAGS = $(DEBUGFLAGS)

# Define a virtual path for .class in the bin directory
vpath %.class $(CLASS_PATH)

all : libMat.so

# $@ matches the target, $< matches the first dependancy
libMat.so : libMat.o
    g++ $(CFLAGS) -W -shared -o $@ $< -lopencv_imgproc

# $@ matches the target, $< matches the first dependancy
libMat.o : Mat2Image.cpp Mat2Image.h
    g++ $(CFLAGS) -fPIC -I/usr/lib/jvm/jdk1.8.0_111/include -I/usr/lib/jvm/jdk1.8.0_111/include/linux -c $< -o $@ 

# $* matches the target filename without the extension
# manually this would be: javah -classpath ../bin HelloJNI
HelloJNI.h : Mat2Image.class
    javah -classpath $(CLASS_PATH) $*

clean :
    rm -f libMat.o libMat.so

【讨论】:

以上是关于将 lib 添加到 jni 应用程序的 makefile的主要内容,如果未能解决你的问题,请参考以下文章

如何将java打包成jar,如何将JNI的.so库和jar添加到应用APK中

VC JNI配置

JNI/NDK开发指南

Android Studio 怎么添加使用第三方jar包及无法编译的问题解决方法

Android Studio 怎么添加使用第三方jar包及无法编译的问题解决方法

如何将“jni/*.c/cpp”文件添加到 CMakeLists.txt 文件中?