目的是采用android + ndk(JNI),使用c/c++编译生成opencv的相关函数的库。
默认jdk已安装好,JAVA_HOME, CLASSPATH, path已设置好。android开发的IDE有两种,Eclipse和Android Studio(http://developer.android.com/sdk/installing/studio.html),后者采用的gradle工具不了解,暂时就不试了。
1. Eclipse CDT + Cygwin环境
Eclipse c/c++开发环境,可以选择eclipse cdt版本下载,或者是Eclipse + CDT插件。
另外还需要有编译工具集/ toolchain,可以直接使用visual c++的命令行工具cl.exe等,或者使用windows下的GNU编译工具Cygwin 或 MinGW。后面两者的区别在于MinGW直接使用win32 API,而cygwin需要依赖单独的dll进行翻译一下,各有优缺点。
这里选用Cygwin64,安装的mirror选择edu站点,一般有IPV6地址,这样速度快不少。下面这个教程很不错:
Cygwin & MinGW (for Windows) How To Install and Get Started
需要注意的是,下载的时候得选上devel (development)目录下的 gcc, g++, gdb, make,这四个不在default选项中。另外后面编译遇到问题,又选择安装了 mingw的几个编译工具。
Eclipse c/c++项目属性里面有好几个地方可以设置编译的环境变量 include/library/path等,而且这些是不依赖系统环境变量设置的。也就是说如果不经常用命令行编译,可以不设置系统环境变量。
- 首先是toolchain的选择。如果没有Microsoft Visual C++选项,则需要安装CDT Visual C++ support插件。
有两种方式安装这个插件,第一种通过 Eclispe Help -> Install New Software -> Juno - http://download.eclipse.org/releases/juno -> Programming Languages ->CDT Visual C++ support。
第二种现在eclipse官方的CDT插件包,里面包含了这个插件,其实也就是org.eclipse.cdt.msw.build_1.0.0.201406111759.jar等。
- 这里需要注意的是Discovery Options选项,默认已勾选automate Discovery of paths and symbols。在Tool Chain Eidtor页面选择不同的toolchain的时候,这个功能可以自动设置相关的环境变量。这个功能简化了环境变量的设置,很实用。另外要知道,不同的配置(Debug / Release)使用单独的设置,包括toolchain。
- 第一处是 C/C++ Build -> Envrironment。不同的toolchain的environment不同,可以手动设置。
- 第二处是 C/C++ Build -> Settings
- 第三处是 C/C++ General -> Paths and Symbols
需要注意的是,路径中如果包含空格,应该用双引号括起来,否则可能会报错(类似Program 错误)。
- VC++ 2010 环境变量设置 / MSVC setting
INCLUDE=
C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\INCLUDE
C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\includeLIB / LIBPATH =
C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\LIB or C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\LIB\amd64
C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\lib or C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\lib\x64Path=
C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\BIN or C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\BIN\amd64
C:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\IDE
debug时候的一个路径映射问题,这个问题会导致debug找不到源文件,从而debug失败
2. JNI相关
java docs里面有Java Native Interface Specification,可以了解个大概。JNI是个双向的接口,java调用c/c++程序可以,c/c++程序也可以通过jni创建JVM实例,从而运行java代码。
JNI主体还是C写的,C++只是在C的基础上进行语言特性方面的包装。JNI是在JVM里面实现的。
JNI编程最麻烦的地方在于java与C/C++数据类型的对应和转换,例如java.lang.String - jstring - char。
学习了下面这个教程,很长。
Java Programming Tutorial Java Native Interface (JNI)
- java / c++代码的输出顺序错乱(printf后面手动调用fflush(stdout),C语言的问题)
- jni.h的位置: %JAVA_HOME%\include
- gcc-4没有编译选项mno-cygwin的解决办法
错误提示建议使用mingw编译工具——没错,只有这个方法。使用cygwin下载安装x86_64-w64-mingw32-gcc、x86_64-w64-mingw32-g++等
编译命令 makefile:
JAVA_HOME = C:\Java\jdk1.7.0_51 all: hello.dll myjni.dll hello.dll: HelloJNI.o x86_64-w64-mingw32-gcc -Wl,--add-stdcall-alias -shared -o $@ $< HelloJNI.o: HelloJNI.c com_zzfei_test_HelloJNI.h x86_64-w64-mingw32-gcc -D __int64="long long" -I"$(JAVA_HOME)\include" -I"$(JAVA_HOME)\include\win32" -o $@ -c $< myjni.dll: MyJNI.o # x86_64-w64-mingw32-g++ -Wl,--add-stdcall-alias -shared -static-libstdc++ -static-libgcc -o $@ $< x86_64-w64-mingw32-g++ -Wl,--add-stdcall-alias -shared -o $@ $< MyJNI.o: MyJNI.cpp com_zzfei_test_MyJNI.h x86_64-w64-mingw32-g++ -D __int64="long long" -I"$(JAVA_HOME)\include" -I"$(JAVA_HOME)\include\win32" -o $@ -c $< clean: rm hello.dll HelloJNI.o myjni.dll MyJNI.o # visual c++ compile command # -LD Create .DLL # -MD link with MSVCRT.LIB # -Fe<file> name executable file #cl MyJNI.cpp -I"%JAVA_HOME%\include" -I"%JAVA_HOME%\include\win32" -Femyjni.dll -MD -LD #cl HelloJNI.c -I"%JAVA_HOME%\include" -I"%JAVA_HOME%\include\win32" -Fehello.dll -MD -LD
makefile的相关规则:GCC and Make Compiling, Linking and Building C/C++ Applications
最后两行注释的是使用vc++ 2010编译的命令,在开始菜单里选择Visual Studio x64 Win64 Command Prompt进入命令行可以自动设置环境变量。
- 在Eclipse中添加javah工具按钮
参数如下
-v -classpath "${project_loc}/bin" -d "${project_loc}/jni" -jni ${java_type_name}
某些错误添加强制类型转换就可以了。
3. Android 开发环境
Android SDK Components
SDK Tools
http://developer.android.com/tools/sdk/tools-notes.html
Platform Tools
http://developer.android.com/tools/help/index.html
ADT Plugin (包含NDK plugin, CDT)?
http://developer.android.com/tools/sdk/eclipse-adt.html
http://developer.android.com/tools/help/adt.html
Build Tools
http://developer.android.com/tools/revisions/build-tools.html
NDK
从r7开始,Google的提供了一个ndk-build的脚本,可以直接用它编译,而不需要使用Cygwin了。
adt bundle:adt-bundle-windows-x86_64-20140702.zip里面的eclipse没有设置ndk路径选项,解决办法:
下载单独的ADT Plugin插件ADT-23.0.2.zip 并安装,或者复制里面的 com.android.ide.eclipse.ndk_23.0.2.1259578.jar (NDK plugin)到eclipse\plugins文件夹。
4. QQQ
- ABI(Application Binary Interface)
- modified UTF-8 以及 JNI中文编码
- (*env)-> env->
- dll size mingw cl & DLL related (EXPORT ...)
- PE, elf
- X86调用约定
- c语言 函数入口 main
- NDK与JNI的关系
- Android Architecture & App workflow
- ...