存档

2016年6月 的存档

多语言编程之 C and Java:JNI 30 分钟入门

2016/06/29 6,323

1 引言

1.1 简介

在实际项目中,很多时候是以多种语言混合开发的。常用的模式是使用 C/C++ 做底层支撑,然后上层辅之以高级语言。 JNI可以使 native 代码与 Java 对象交互,而不会像 Java 代码中的功能那样受到诸多限制, 往往充作 Java 与 C/C++/Assembly 语言的粘合剂。

JNI 明确分开了 Java 代码与 native 代码的执行,为两者的通信定义了一套清晰的API.避免 native 代码对 JVM 的直接内存引用。

2 JNI 入门

2.1 JNI 调用 C

2.1.1  java 中的 native 方法声明

HelloJNI.java

当HelloJNI类加载的时候,静态初始化调用 System.loadLibrary() 来加载本地库 hello.dll(或libhello.so)。如果不能加载 hello 库,会抛出 UnsatisfiedLinkError 异常。
然后我们使用 native 关键字声明了 native 方法 sayHello() ,这表明该方法是使用其它语言实现的。
最后 main() 方法实例化了 HelloJNI 并调用了 sayHello().
然后我们编译这个类:

2.1.2  生成 C/C++ 头文件

使用 javah 创建头文件:

会得到如下 .h 文件 HelloJNI.h

这份自动生成的头文件里声明一个 C 函数 Java_HelloJNI_sayHello:

这个方法名是由javah转换来的,转换规则为:

包名中的 点 会被转换为 下划线
函数中带有两个参数(虽然我们在本例中并没有使用这两个参数)

  • JNIEnv*: 指向 JNI environment ,提供对 JNI 方法的访问
  • jobject: 指向 this Java 对象

2.1.3 C 代码的实现

HelloJNI.c

这个实现将在控制台打印万能的 "Hello World!"
文件中包含了 jni.h 头文件。这个头文件由 java 提供,位于 %JAVA_HOME%/include 路径下(Windows下还需要引用 %JAVA_HOME%/include/win32).

2.1.4 编译 C 库

接下来,编译这个 c 文件:

2.1.5 检查成果

继续阅读

NDK 无法 Debug的一个问题

2016/06/15 5,038

在使用 Android NDK 进行 native 代码调试时,尽管 Android.mk/Application.mk 与Gradle 中都指定了Debug编译,但 C 代码的断点一直无法命中。 排查后,使用 greadelf(Mac)/readelf(Unix) –header x.so 查看编译出来的 so ,发现其中没有debug信息,那么一定是 ndk-build 的过程中出现了问题。无意中发现ndk-build 编译完成以后,又调用了 strip ,这一步将 so 中的一些无用的符号移除了,当然也包括debug信息。

在 Android.mk 中将 strip 这一步做个处理,使其在debug时不执行:

 

如何在windows下编译cairo

2016/06/14 8,838

cairo  是一个免费的矢量绘图软件库,它可以绘制多种输出格式。cairo 支持许多平台,如  Linux、BSD、OSX等,当然,还有  Windows。
cairo 官网提供了在 windows 下的编译方法,详情可戳这里。尽管它给出了看起来很详细的步骤,但在实际编译中,你有可能会遇到各种各样的问题。

我们先从官网的步骤开始。

  1. 下载并编译 zlib .
  2. 下载并编译 libpng .
  3. 安装 MozillaBuild编译环境。( 注意安装路径下不要有空格) .
  4. 找到 MozillaBuild 的安装路径,找到 VC++ 对应版本的启动脚本,如 start-shell-msvc2015.bat,按官网给出的方式进行修改,定义出 zlib \ libpng 等 lib、include 等的路径 .
  5. 运行修改后的 bat,到 pixman 所在路径下,运行 make 命令进行编译 .

进行到这一步的时候,基本就无法进行下去了。因为在这一步开始就会出现各种各样的错误
下面我们将从这里开始,一步一步完成cairo的编译。

1.  修改MozillaBuild脚本:

  • 打开 VS 版本对应的 bat 文件,注意 MOZ_MSVCBITS 的值 :这里将值改为 32。我们将编译 32 位版本。
  • 打开 start-shell.bat 。在 "REM Reset some env vars and set some others." 内容下方,按照官网上给出的方式,指定 zlib, libpng 的 lib 和 include 所在路径。
  • 如果你的PC是 64 位,那么 MozillaBuild  会默认使用 64 的 VS 进行编译,可能会引发平台不匹配的问题。此时需要将 "REM Prepend MSVC paths."  下面的

    改为

2.  修改 pixman-version.h.in

进入 pixman/pixman 文件夹下,修改 @PIXMAN_VERSION_MAJOR@ ,  @PIXMAN_VERSION_MINOR@  , @PIXMAN_VERSION_MICRO@ 的值为对应的版本号。

这里有一份修改好的文件,版本号为 0.35.1 ,可直接取用

3.  编译pixman

运行 start-shell-msvc2015.bat ,转到 pixman 路径下,运行

如果成功,则 pixman/pixman 路径下有 release 文件夹,内有 pixman-1.lib

4.  修改Makefile.win32.common

在 cairo/build/ 路径下找到  Makefile.win32.common 文件,指定 zlib 和 libpng 所在的路径( ZLIB_PATHLIBPNG_PATH)。

修改 zdll.lib 为 zlib.lib。

5.  编译 cairo

转到 cairo/ 路径下运行命令:

如不出意外,此步应编译成功

6.  提取 include 头文件

在 cairo/ 路径下,添加以下脚本并执行:

至此,cairo 的编译已经完成。