J.P*_*.P. 2 c++ java-native-interface android static-libraries
我已经看到了类似于这个问题的问题,但情景并不完全相同,我也无法找到适用于我的问题的答案.
我有一个C++库的源代码.我们需要将此库用作Android应用程序的一部分,但它也需要可供第三方用作C++库.
我有一个makefile,使用ndk的编译器从库的源代码生成.a文件.那是纯粹的C++部分.
在Java部分,我有一个简单的演示项目,其中包含一个包含按钮的简单活动.按下按钮时,将调用本机代码.
只要我不尝试从JNI函数调用库中的函数,一切正常.
以下是图书馆的来源:
SimpleMath.h
int Add(int aNumber1, int aNumberB);
Run Code Online (Sandbox Code Playgroud)
SimpleMath.cpp
#include "SimpleMath.h"
int Add(int aNumberA, int aNumberB)
{
return aNumberA + aNumberB;
}
Run Code Online (Sandbox Code Playgroud)
在生成文件
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
Run Code Online (Sandbox Code Playgroud)
在java方面,这些是文件:
你好,jni.c
#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!");
}
Run Code Online (Sandbox Code Playgroud)
Android.mk
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)
Run Code Online (Sandbox Code Playgroud)
Application.mk
APP_MODULES := my_simple_library hello-jni
Run Code Online (Sandbox Code Playgroud)
正如我所说,当我从Java应用程序中的jni本机代码实际使用库中的功能时,问题就出现了.
现在,我不再确定我的问题是在静态库的makefile中还是在Android.mk上.我首先想到它必须与库本身的生成有关,但是在这一点上,在看到Android.mk中有很多我不知道的选项后,我不得不承认我没有任何线索.
还有什么..?
哦,是的,我也注意到我的纯C++库正在使用cpp扩展,而java项目中的jni代码正在使用c扩展.我试图让后者使用cpp,但编译器抱怨.这可能是问题的一部分吗?
我在尝试编译Android.mk文件时得到的错误代码是"未定义的符号",因此,hello-jni.c中不可见的simple_library.a中的函数列表(实际上有1个函数)因为它是C++而不是普通的C?
您可能会注意到的另一件事是我正在尝试在自己的makefile上构建静态库,而不是使用Android.mk生成静态库; 这是有原因的,但是在这一点上,如果我必须让它由Android.mk生成,我也会很高兴,如果这是它需要的.
我没有看到任何方法在这里添加附件,以便与项目共享一个zip.让我知道是否有我遗漏的东西..否则代码在bitbucket的仓库中,所以我可以轻松地与任何拥有帐户的人共享它.
谢谢你的回答.
你写了很多正确的东西,但你只缺少一个.
函数的名称在C++中被破坏了.在.so文件中,您没有获得"添加"符号,而是"Add @ 8i".为了避免破坏只是使用
extern "C" int Add(int x, int y)
Run Code Online (Sandbox Code Playgroud)
.cpp文件和.h中的声明.
通常一个人也加了
/// Some .h file
#ifdef __cplusplus
extern "C" {
#endif
/// Your usual C-like declarations go here
#ifdef __cplusplus
} // extern "C"
#endif
Run Code Online (Sandbox Code Playgroud)
而且
extern "C"
Run Code Online (Sandbox Code Playgroud)
对于.cpp文件中的每个导出函数.
| 归档时间: |
|
| 查看次数: |
8893 次 |
| 最近记录: |