背景
上篇博文已实现了JNA调用DLL取样器开发,进行功能性接口测试已满足,但是在进行性能测试这块就差强人意了。JNA使用起来确实是方便,但是在调用c++接口性能损耗这块还是蛮大的,测试下来JNA开发跑下来吞吐量三千多,之前做的纯C++测试工具跑下来吞吐量能达到七八千。
实现步骤
经查找资料,JNI实现调用c需要几个步骤
1、新建一个Java类,该类中定义自己需要的 C 端的native方法;
2、根据该类编译生成的.class文件生成 C 所需要的头文件,也就是常说的.h文件。
3、根据生成的 .h 文件编写C的功能实现,最后生成对应的dll(windows),so(linux)文件,此处需要注意:生成的dll 的位数需要和Java环境的位数相同,否则会报错。
4、拷贝生成的dll文件到系统环境配置的某一文件夹下
5、运行。
1、java类实现
public class fixapi50 {
{
/**
* 系统加载其他的语言的函数
*/
String apiPath=Platform.isWindows()?"jniFixApi":"jnifixapi";
System.loadLibrary(apiPath);
}
//申明动态库文件中的方法
/**
* 5.1 接口库初始化
* @return 返回true表示初始化成功;False表示失败
*/
public native boolean Initialize();
/**
* 5.2 接口库卸载
* @return 返回true表示初始化成功;False表示失败
*/
public native boolean Uninitialize();
//剩余方法省略。。。。。。
}
System.loadLibrary 参数为库文件名,不包含库文件的扩展名。
注意linux环境,使用的是“jnifixapi”,实际对应的“libjnifixapi.so”文件,名字相差了前面的lib
System.load 参数为库文件的绝对路径,可以是任意路径。
例如你可以这样载入一个windows平台下JNI库文件:
System.load(“C://Documents and Settings//TestJNI.dll”);。
刚开始使用的load加载绝对路径,开发起来方便,但是打包后给他人使用增加了使用负担和难度,最后还是换成了loadLibrary,增加了第四步骤library配置的步骤
2、.h头文件生成
使用javah命令,在包路径的最外面文件夹,执行生成命令。com.jmeter.jna.fixapi为包名+类名生成路径名_包名.h头文件。
这边生成头文件也是头疼了很久,因为执行路径不对,一定要是包路径的最外层文件夹执行
3、编写c,生成dll和so文件
这块他人做好使用
4、dll环境变量配置
windows系统
在“Path”中添加.dll所属路径
linux系统
设置系统变量LD_LIBRARY_PATH来添加java.library.path(该设置只会对当前打开的shell窗口有效,因此每次打开新的shell运行程序不停地设置LD_LIBRARY_PATH)
export LD_LIBRARY_PATH=LD_LIBRARY_PATH:/home/jinbing
或者永久设置
vim ~/.bash_profile
打开~/目录下打开.bash_profile文件,设置环境变量如下:
LD_LIBRARY_PATH=dir:$LD_LIBRARY_PATH
export LD_LIBRARY_PATH
5、运行
取样器具体开发过程参考上一文章,JNI调用dll过程如上。实践下来,同一个接口进行测试,JNI实现比JNA实现吞吐量来讲快了一倍不止。可以做性能测试使用了。