使用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) 进行许可。