‘壹’ 如何调试android NDK 交叉编译的cpp文件
主要讲一下具体的步骤,具体的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_mp(filename, outname);
}
其中hprof_mp是纯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-mper
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的当然不用引入这些啦~
‘贰’ 如何交叉编译应用程序,技巧,注意事项
如果你程序中需要读取某个文件夹下的文件则须注意:
假如你的所有文件都放在一个名为test的文件夹下,当然也包括main.cpp,同时程序需要读取test/input文件夹下的文件,比如说图片,这时在程序中路径你就需按如下写:input/(请注意这个斜线的方向)
不知道为什么OpenCV程序中如果有imwirte、waitKey函数(不知道是哪个的原因还是都有),虽然交叉编译会通过,但当你把编译好的二进制可执行程序拷贝到ARM平台下执行,会出现错误。(可能是当初OpenCV库交叉编译时没编译完全,当然这主要是交叉编译平台缺少某些软件;也可能是ARM平台系统中缺少某些软件造成的)
‘叁’ 如何使用 sdk交叉编译ros
使用ros_qtc_plugin插件新建项目
使用插件新建项目Import ROS
Workspace选项仅新建工作空间导入现工作空间新建文件ROS面Package、Basic
Node等选项创建package节点、launch文件、urdf文件等
现我创建新catkin工作空间,并且面创建package
1、新建项目
文件——新建文件或项目选择Import ROS Workspace——choose图
填写catkin工作空间名字位置图
我Namecatkin工作空间文件夹名字相同(同)名catkin_new选择浏览——创建文件夹创建名catkin_new文件夹图按车再选择打
现框询问新建工作空间未初始化否执行初始化我选择yes
相于执行catkin_init_workspace命令使工作空间初始化
点击Generate Project File再点击步
项目管理步骤配置版本控制系统我选择完图
建工作空间catkin_new空图
2、创建package
接我工作空间创建新package
catkin_new面src右键单击选择添加新文件图
选择ROS——package——choose
填写package名字test1
填写作者(Authors)维护者(Maintainers)Qt环境部没配置文支持请要用文否则新建package或者新建package面package.xml空文件
DependenciesCatkin栏填写依赖通用C++写节点需要添加roscpp依赖
图
点击完
3、添加新节点
目前package空没任何节点
我test1src文件夹右键单击选择添加新文件
选择ROS——Basic Node——choose创建节点新建.cpp文件
节点名称写node1则名node1.cpp源文件
用ROS模板新建node1.cpp源文件图自Hello World程序
4、编译节点
让编译执行文件我需要编辑test1makefile图
test1CMakeLists.txt加面几行意思node1.cpp编译名node1节点
add_executable(node1 src/node1.cpp)
target_link_libraries(node1
${catkin_LIBRARIES}
)
‘肆’ C++交叉编译 请帮忙看看是哪个库没有链接
C++交叉编译 请帮忙见见是哪个库没有链接
www.MyException.Cn 网友分享于:2013-10-12 浏览:103次
C++交叉编译 请帮忙看看是哪个库没有链接
我在交叉编译一个cpp程序的时候,提示说:
undefined reference to `std::_Rb_tree_decrement(std::_Rb_tree_node_base const*)'
undefined reference to `std::_Rb_tree_insert_and_rebalance(bool, std::_Rb_tree_node_base*, std::_Rb_tree_node_base*, std::_Rb_tree_node_base&)'
undefined reference to `std::_Rb_tree_increment(std::_Rb_tree_node_base const*)'
undefined reference to `android::RefBase::decStrong(void const*) const'
是不是我在链接 的时候,忘记链接哪个库了,请帮忙看下,谢谢!
我链接的库有:-lcutils -ldl -lstlport -lc -lm -lz -ldl -llog -lstdc++ -lstagefright -lbinder
但还是 出现上面 的错误。请问下为什么?
分享到:
------解决方案--------------------
std::_Rb_tree
应该是map或者set用到的红黑树啊。
头文件是bits/stl_tree.h
库的话应该是-lstdc++, 或者-lstlport啊
为了排除静态库原因引起的问题,建议楼主试试在最后在链接一下这几个库试试
-lcutils -ldl -lstlport -lc -lm -lz -ldl -llog -lstdc++ -lstagefright -lbinder -lstlport -lstdc++ -lstl
加上红色部分
‘伍’ 如何将json-cpp库移植到arm-linux下使用
1 下载源码;
2 交叉编译;
3 将libjscon-XXX.so 拷贝到 开发板;
4 编写运用程序,加入json头文件,交叉编译运用程序,编译时加上-json 引入json库文件。
‘陆’ 兄弟我最近刚学QT,到了交叉编译这一块,make之后老是出现 下面的错误
交叉编译的时候要加上配置要加上:-embedded arm
例如:
./configure \
-no-pch \
-no-dbus \
-no-nas-sound \
-no-opengl \
-no-sm \
-no-xshape \
-no-xinerama \
-no-xcursor \
-no-xfixes \
-no-xrandr \
-no-xrender \
-no-fontconfig \
-no-xkb \
-no-glib \
-little-endian \
-no-mmx -no-3dnow -no-sse -no-sse2 \
-embedded arm \
-xplatform qws/linux-arm-g++ \
-qconfig smal
希望可以帮助到你
‘柒’ 如何为嵌入式开发建立交叉编译环境
TARGET_LIBGCC2-CFLAGS = -fomit-frame-pointer -fPIC这一行改为TARGET_LIBGCC2-CFLAGS = -fomit-frame-pointer -fPIC -Dinhibit_libc -D__gthr_posix_h你如果没定义 -Dinhibit,编译时将会报如下的错误../../gcc-2.95.3/gcc/libgcc2.c:41: stdlib.h: No such file or directory ../../gcc-2.95.3/gcc/libgcc2.c:42: unistd.h: No such file or directory make[3]: *** [libgcc2.a] Error 1 make[2]: *** [stmp-multilib-sub] Error 2 make[1]: *** [stmp-multilib] Error 1 make: *** [all-gcc] Error 2 如果没有定义 -D__gthr_posix_h,编译时会报如下的错误In file included from gthr-default.h:1, from ../../gcc-2.95.3/gcc/gthr.h:98, from ../../gcc-2.95.3/gcc/libgcc2.c:3034: ../../gcc-2.95.3/gcc/gthr-posix.h:37: pthread.h: No such file or directory make[3]: *** [libgcc2.a] Error 1 make[2]: *** [stmp-multilib-sub] Error 2 make[1]: *** [stmp-multilib] Error 1 make: *** [all-gcc] Error 2 还有一种与-Dinhibit同等效果的方法,那就是在你配置configure时多加一个参数-with-newlib,这个选项不会迫使我们必须使用newlib。我们编译了bootstrap-gcc后,仍然可以选择任何c库。接着就是配置boostrap gcc, 后面要用bootstrap gcc 来编译 glibc 库。$cd ..; cd build-boot-gcc $../gcc-2.95.3/configure --target=$TARGET --prefix=$PREFIX >--without-headers --enable-languages=c --disable-threads 这条命令中的 -target、--prefix 和配置 binutils 的含义是相同的,--without-headers 就是指不需要头文件,因为是交叉编译工具,不需要本机上的头文件。-enable-languages=c是指我们的 boot-gcc 只支持 c 语言。--disable-threads 是去掉 thread 功能,这个功能需要 glibc 的支持。接着我们编译并安装 boot-gcc$make all-gcc $make install-gcc 我们来看看 $PREFIX/bin 里面多了哪些东西$ls $PREFIX/bin 你会发现多了 arm-linux-gcc 、arm-linux-unprotoize、cpp 和 gcov 几个文件。Gcc-gnu 的 C 语言编译器Unprotoize-将 ANSI C 的源码转化为 K&R C 的形式,去掉函数原型中的参数类型。Cpp-gnu的 C 的预编译器Gcov-gcc 的辅助测试工具,可以用它来分析和优程序。
‘捌’ 交叉编译armlinuxgcc wchar.h: No such file or directory 不仅如此所有的C语言头文件都找不到
我的也是这个问题 交叉编译环境搭建后 arm-linux-gcc -v 显示
No such file or directory 使用which命令可以找到,环境变量没有问题,更详细的描述问题就是which找到的命令所在的目录下的所有命令都是同样的问题。
果然问题的解决点就在我用的是64位系统,使用 sudo apt-get install ia32-libs命令就可以解决
希望对你有所帮助!
‘玖’ makefile的选项CFLAGS,CPPFLAGS,LDFLAGS和LIBS的区别
看看如下选项:
LDFLAGS = -L/var/xxx/lib -L/opt/MySQL/lib
LIBS = -lmysqlclient -liconv
这就明白了。LDFLAGS告诉链接器从哪里寻找库文件,LIBS告诉链接器要链接哪些库文件。不过使用时链接阶段这两个参数都会加上,所以你即使将这两个的值互换,也没有问题。
说到这里,进一步说说LDFLAGS指定-L虽然能让链接器找到库进行链接,但是运行时链接器却找不到这个库,如果要让软件运行时库文件的路径也得到扩展,那么我们需要增加这两个库给"-Wl,R"
LDFLAGS = -L/var/xxx/lib -L/opt/mysql/lib -Wl,R/var/xxx/lib -Wl,R/opt/mysql/lib
如 果在执行./configure以前设置环境变量export LDFLAGS="-L/var/xxx/lib
-L/opt/mysql/lib -Wl,R/var/xxx/lib -Wl,R/opt/mysql/lib"
,注意设置环境变量等号两边不可以有空格,而且要加上引号哦(shell的用法)。那么执行configure以后,Makefile将会设置这个选项,
链接时会有这个参数,编译出来的可执行程序的库文件搜索路径就得到扩展了。
PS:-Wl,R在GraphicsMagick环境下,用为-R, 也就是LDFLAGS = -L/var/xxx/lib -R/var/xxx/lib
CFLAGS 或 CPPFLAGS的用法
CPPFLAGS='-I/usr/local/libjpeg/include -I/usr/local/libpng/include'