『壹』 如何調試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'