如何调试android NDK 交叉编译的cpp文件

如何调试android NDK 交叉编译的cpp文件,第1张

主要讲一下具体的步骤,具体的ndk指令我就不说了,贴的文章都有:

首先是写一个.java文件,本例中是HprofDumper.java

具体如下:

public class HprofDumper {

public native boolean hprofDumper(String filename, String outname)

}

然后用命令javac HprofDumper.java 生成.class文件

再用javah HprofDumper 生成相应的.h文件

生成的.h文件如下

#include

#ifndef _Included_HprofDumper

#define _Included_HprofDumper

#ifdef __cplusplus

extern "C"世搜 {

#endif

JNIEXPORT jboolean JNICALL Java_HprofDumper_hprofDumper

(JNIEnv *, jobject, jstring, jstring)

#ifdef __cplusplus

}

#endif

#endif

然后只需要在对应的.cpp文件完成相应函数即可,核心代码如下:

#include "HprofDumper.h"

#include "hprof.h"

JNIEXPORT jboolean JNICALL Java_HprofDumper_hprofDumper

(JNIEnv *env, jobject obj, jstring in_file, jstring out_file)

{

const char *filename = env->GetStringUTFChars(in_file, 0)

const char *outname = env->GetStringUTFChars(out_file, 0)

return hprof_dump(filename, outname)

}

其中hprof_dump是纯c++代码,引入即可。

有一点需要注意,标红了已经,就是生成的.h文件函数并没具体形参名字,只有形参类型,在.cpp文件中要加橡模入相应的形参名字,本例为env、 obj、 in_file和out_file。

还有一点c和c++的区别,就是env的使用。

本例中C++为env->GetStringUTFChars(in_file, 0)

如果是C就应该改为(env)->GetStringUTFChars(env,in_file, 0)

调用Java类型 : C中调用Java中的String类型为 jstring

C语言方法名规则 : Java_完整包名类名_方法名(JNIEnv *env, jobject thiz), 注意完整的类名包名中包名的点要用 _ 代替

参数介绍 : C语言方法中有两个重要的搜如历参数, JNIEnv *env, jobject thiz

-- JNIEnv参数 : 该参数代表Java环境, 通过这个环境可以调用Java中的方法

-- jobject参数 : 该参数代表调用jni方法的类,

调用jni.h中的NewStringUTF方法 : 该方法的作用是在C语言中创建一个Java语言中的String类型对象, jni.h中是这样定义的 jstring (*NewStringUTF)(JNIEnv*, const char*), JNIEnv 结构体中包含了 NewStringUTF 函数指针, 通过 JNIEnv 就可以调用这个方法

完成代码编写后,在当前目录下完成Android.mk和Application.mk的编写

首先是Android.mk

本例中为:

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

LOCAL_MODULE := hprof-dumper

LOCAL_C_INCLUDES += external/stlport/stlport

LOCAL_C_INCLUDES += bionic

LOCAL_C_INCLUDES += bionic/libstdc++/include

LOCAL_SRC_FILES := HprofDumper.cpp \

xx.cpp \

xx.cpp \

xx.cpp \

xx.cpp \

xx.cpp \

xx.cpp \

xxx.cpp

LOCAL_SHARED_LIBRARIES := libstlport

include $(BUILD_SHARED_LIBRARY)

注意标红的是最关键的,LOCAL_C_INCLUDES 顾名思义是需要的头文件的所在的目录,那三个参数主要为了引入STL,最重要!!LOCAL_SHARED_LIBRARIES 我一直生成失败就是没加这个参数,不光要引入头文件,还要引入具体的lib,这就是这个字段的作用。

具体字段的作用:

-- LOCAL_PATH : 代表mk文件所在的目录

-- include $(CLEAR_VARS) : 编译工具函数, 通过该函数可以进行一些初始化 *** 作

-- LOCAL_MODULE : 编译后的 .so 后缀文件叫什么名字

-- LOCAL_SRC_FILES: 指定编译的源文件名称

-- include $(BUILD_SHARED_LIBRARY) : 告诉编译器需要生成动态库

Applicaion.mk中就一行

APP_STL = stlport_static

表示使用stl静态库。

注意:我用了STL,大家没有用STL的当然不用引入这些啦~

1. 定义相关的目录(请修改为自己的相关目录) $ export NDKROOT=/opt/android/android-ndk-r10 $ export SYSROOT=$NDKROOT/platforms/android-19/arch-arm $ export GCC=$NDKROOT/toolchains/arm-linux-androideabi-4.6/prebuilt/linux-x86_64/bin/arm-linux-androideabi-gcc 2. 编译代码 $ $GCC -o main.out main.c --sysroot=$SYSROOT 3. 执行程序 $ adb push main.out /data/local/ $ adb shell $ /data/local/main.out 其核心思想其实很简单, 就是使用NDK提供的arm-linux-androideabi-gcc代替Linux下的gcc工具, 使用NDK提供的C头文件/库文件目录代替 Linux 下默认的目录, 其实, 使用gcc编译的时候默认的 sysroot设置为了本机的"/"目录, 等价于如下命令如蠢 : $ gcc -o main.out main.c --sysroot=/ 关备橡喊于如何在命令行下使用Android NDK交叉编译工具就介绍到这里了,希望对大仿野家有所帮助


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/tougao/12245835.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-22
下一篇 2023-05-22

发表评论

登录后才能评论

评论列表(0条)

保存