首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Android:如何使用JNI代码中现有的C++静态库?

Android:如何使用JNI代码中现有的C++静态库?
EN

Stack Overflow用户
提问于 2012-07-05 16:30:36
回答 1查看 9.4K关注 0票数 2

我见过类似于这个问题的问题,但情况并不完全相同,我也无法得到一个对我的问题有效的答案。

我有一个C++库的源代码。我们需要将这个库作为android应用程序的一部分使用,但它也需要供第三方作为C++库使用。

我有一个makefile,它使用ndk的编译器从库的源代码中生成.a文件。这是纯C++部分。

在Java部分,我有一个简单的演示项目,其中包含一个按钮。当按下按钮时,将调用本机代码。

只要我不尝试从JNI函数调用库中的函数,一切都可以正常工作。

以下是图书馆的资料来源:

SimpleMath.h

代码语言:javascript
复制
int Add(int aNumber1, int aNumberB);

SimpleMath.cpp

代码语言:javascript
复制
#include "SimpleMath.h"

int Add(int aNumberA, int aNumberB)
{
  return aNumberA + aNumberB;
}

makefile

代码语言:javascript
复制
APP      = simple_app
LIBRARY  = simple_library.a
OBJECTS  = SimpleMath.o
CFLAGS   = -Wall -pedantic
NDK_PATH = /home/jug/perforce/jug_navui_personal_main/Env/Linux/Android/ndk/r7c
CXX      = $(NDK_PATH)/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-g++
AR       = $(NDK_PATH)/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-ar
SYSTEM_LIBS = -lstdc++ -lm
INCLUDE_PATH += ${NDK_PATH}/platforms/android-9/arch-arm/usr/include

all: $(LIBRARY)

$(LIBRARY): 
    $(CXX) -c SimpleMath.c
    $(AR) rcs simple_library.a SimpleMath.o

clean:
    rm *.o *.a

在java端,这些文件是:

hello-jni.c

代码语言:javascript
复制
#include <string.h>
#include <jni.h>

#include "../../../native/simple_library/SimpleMath.h"

jstring Java_com_amstapps_samples_draft08jni_MainActivity_helloJni(JNIEnv* env, jobject obj)
{
    // Uncommenting the line below results in undefined-symbol compile error
    //int d = Add(1, 2);

    return (*env)->NewStringUTF(env, "Hello from JNI!");
}

Android.mk

代码语言:javascript
复制
LOCAL_PATH:= $(call my-dir)

include $(CLEAR_VARS)
LOCAL_MODULE := my_simple_library
LOCAL_ARM_MODE := arm
LOCAL_SRC_FILES := ../../../native/simple_library/simple_library.a
include $(PREBUILT_STATIC_LIBRARY)
#include $(BUILD_STATIC_LIBRARY)

include $(CLEAR_VARS)
LOCAL_MODULE_TAGS    := eng
LOCAL_ARM_MODE       := arm
#LOCAL_PRELINK_MODULE := false
LOCAL_MODULE         := hello-jni
LOCAL_SRC_FILES      := hello-jni.c
LOCAL_C_INCLUDES     := ../../../android/native/simple_library
LOCAL_STATIC_LIBRARIES := my_simple_library
#LOCAL_WHOLE_STATIC_LIBRARIES := my_simple_library
include $(BUILD_SHARED_LIBRARY)

Application.mk

代码语言:javascript
复制
APP_MODULES := my_simple_library hello-jni

正如我所说,当我实际使用java应用程序中jni本机代码中的库中的功能时,问题就出现了。

现在,我不再确定我的问题是在静态库的makefile中还是在Android.mk上。我最初认为这肯定与库本身的产生有关,但在这一点上,在看到在Android.mk中有这么多我不知道的选项之后,我不得不承认我没有任何线索。

还有什么..?

哦,是的,我还注意到我的纯C++库使用cpp扩展,而java项目中的jni代码使用的是c扩展。我试图让后者也使用cpp,但是编译器会抱怨。这可能是问题的一部分吗?

我在编译Android.mk文件时得到的错误代码是“未定义的符号”,那么,simple_library.a中的函数列表(实际上只有一个函数)因为它是C++而不是普通的C,所以对hello-jni.c不可见吗?

另一件您可能会注意到的事情是,我试图在它自己的makefile上构建静态库,而不是用Android.mk生成它;这是有原因的,但在这一点上,如果需要Android.mk生成它,我也会很高兴。

我看不出有什么方法可以在这里添加一个附件,以便与项目共享一个压缩。如果我遗漏了什么就告诉我..。否则,代码在bitbucket的一个仓库中,所以我可以很容易地与任何在那里有帐户的人共享它。

谢谢你的回答。

EN

回答 1

Stack Overflow用户

发布于 2012-07-05 20:35:19

你写了很多正确的东西,但你只少了一件。

函数的名称在C++中损坏。在.so文件中,您不会得到"Add“符号,而是类似于"Add@8i”之类的符号。若要避免损坏,只需使用

代码语言:javascript
复制
extern "C" int Add(int x, int y)

声明在.cpp文件和.h中。

通常还会添加

代码语言:javascript
复制
/// Some .h file
#ifdef __cplusplus
extern "C" {
#endif

/// Your usual C-like declarations go here

#ifdef __cplusplus
} // extern "C"
#endif

代码语言:javascript
复制
extern "C"

对于.cpp文件中的每个导出函数。

票数 7
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/11348646

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档