使用JNative,在Java中传递一个C/C++结构参数到动态库中
用C++写的动态库的导出方法的代码如下:
1struct TestStruct {
2 int a;
3 int b;
4};
5
6extern "C" __declspec(dllexport) TestStruct* ShowStruct(TestStruct* testStruct)
7{
8 cout << "在动态库中打印:传入动态库中的结构成员a的值为:" << testStruct->a << endl;
9
10 //改变传入结构成员a的值为100
11 testStruct->a = 100;
12 return testStruct;
13}方法ShowStruct传入一个结构指针,并且反回一个结构指针,这里是同一个结构指针。
使用JNative的Java调用动态库中方法ShowStruct的代码如下:
1JNative nm = new JNative("D:\\vcprj\\testDll\\callDll\\Sample.dll", "ShowStruct", false);
2nm.setRetVal(Type.PSTRUCT);
3Pointer pTestStruct = new Pointer(new HeapMemoryBlock(4 + 4));
4pTestStruct.setIntAt(0, 50);
5nm.setParameter(0, pTestStruct);
6nm.invoke();
7System.out.println("Java调用动态库后打印结构成员 a 的值为:" + pTestStruct.getAsInt(0));
8nm.dispose();
9pTestStruct.dispose();从上面的代码可出,Java端需要先new一个Pointer,根据C/C++的相应结构指定多少字节的内存。结构TestStruct是两个int组成,在C/C++中一般也是用4个字节表示一个整数,这里可能要考虑到不同编译器的整数可能长度不一样,结构中字节对齐方式也会影响到对Pointer的声明。
设定nm(本地方法NativeMethod)的返回值类型,我还没有搞清楚动态方法中返回的指针类型应如何获取到相应的值
再设置本地方法的参数,注意调用完之后要记得释放资源。
执行这段调用动态库的Java程序的输出为:
在动态库中打印:传入动态库中的结构成员a的值为:50
Java调用动态库后打印结构成员a的值为:100
由此可知Java确实把C/C++结构指针以Point的方式传入到了动态库的方法中,并且在动态库中也确实改写的结构成员的数据。
不过看定位动态库中的方法的方式,难道每次调用同一个动态库的不同方法,每次都需要重新装载这个动态库吗,是否能装载一次动态库,以后都只定位方法,最后释放动态库? 永久链接 https://yanbin.blog/jnative-java-pass-struct/, 来自 隔叶黄莺 Yanbin's Blog
[版权声明]
本文采用 署名-非商业性使用-相同方式共享 4.0 国际 (CC BY-NC-SA 4.0) 进行许可。