美文网首页java高级开发
jna对结构体、指针、引用、拷贝参数传递的使用

jna对结构体、指针、引用、拷贝参数传递的使用

作者: 老鼠AI大米_Java全栈 | 来源:发表于2022-10-13 17:11 被阅读0次

虽然之前也用过jna,但是对于[结构体]的传递、指针参数数与返回值、引用参数与返回值、拷贝变量传递使用没有总结。

先上生成DLL代码:
dllTest.h

#ifndef DLLTEST_H
#define DLLTEST_H

struct  myStruct
{
    int a;
    int b;
};
 
extern "C"{
    __declspec(dllexport) int addNormal(myStruct ms);
    __declspec(dllexport) void addPrt(myStruct *ms, int *ret);
    __declspec(dllexport) int addRef(myStruct &ms);
};
#endif

dllTest.cpp : 定义 DLL 应用程序的导出函数

#include "stdafx.h"
#include "dllTest.h"
 
 
__declspec(dllexport) int addNormal(myStruct ms){
    return ms.b + ms.a;
}
 
__declspec(dllexport) void addPrt(myStruct *ms, int *ret){
    *ret = ms->a + ms->b + 1;
}
 
__declspec(dllexport) int addRef(myStruct &ms){
    return ms.a + ms.b + 2;
}

生成的DLL用查看器查看:


image.png

C++测试代码:
dllUse.cpp : 定义控制台应用程序的入口点。
需要新建一个ConsoleApplication项目,将生成的test.h,test.dll,test.lib文件复制到项目中,与cpp文件同级并导入h和lib文件。

#include "MyDll.h"
#pragma comment(lib, "MyDll.lib")    //使用注释方式引入库或编译目录
 
int main()
{
    myStruct ms;
    ms.a = 1;
    ms.b = 2;
 
    myStruct *pms = &ms;
 
    printf("%d",addNormal(ms));
    
    int sum;
    addPrt(&ms,&sum);
 
    printf("%d",sum);
 
    printf("%d\n",addRef(ms));
    
    system("Pause");
    return 0;
}

运行结果:


image.png

java调用代码:

import java.util.ArrayList;
import java.util.List;

import com.sun.jna.Library;
import com.sun.jna.Native;
import com.sun.jna.Structure;
import com.sun.jna.ptr.IntByReference;

public interface dllTestApi extends Library {

    public static dllTestApi dta = (dllTestApi)Native.loadLibrary("dllTest", dllTestApi.class);
    
    public static class myStructur extends Structure{
        public static class ByReference extends myStructur implements Structure.ByReference{
        }
        
        public static class ByValue extends myStructur implements Structure.ByValue{
        }
        
        public int a;
        public int b;
 
        @Override
        protected List<String> getFieldOrder() {
            List<String> Field = new ArrayList<String>();
            Field.add("a");
            Field.add("b");
 
            return Field;
        }
    }   
    
    int addNormal(myStructur.ByValue ms);
    void addPrt(myStructur.ByReference pms,IntByReference sum);
    int addRef(myStructur.ByReference rms);
}

main:

import com.sun.jna.ptr.IntByReference;
 
public class test {
 
    public static void main(String[] args){
        
        dllTestApi.myStructur.ByReference pmysStructur = new dllTestApi.myStructur.ByReference();
        pmysStructur.a = 1;
        pmysStructur.b = 3;
        
        IntByReference ib = new IntByReference();
        dllTestApi.dta.addPrt(pmysStructur,ib);
        System.out.println(ib.getValue());
        
        System.out.println(dllTestApi.dta.addRef(pmysStructur));
        
        dllTestApi.myStructur.ByValue vmysStructur = new dllTestApi.myStructur.ByValue();
        vmysStructur.a = 1;
        vmysStructur.b = 3;     
        
        System.out.println(dllTestApi.dta.addNormal(vmysStructur));     
    }
}

运行结果:


image.png

结论:

  1. 只要涉及到结构体的传递,必须使用ByReference或者ByValue中的一种
  2. 指针和引用的传递使用ByReference
  3. 拷贝参数传递使用ByValue

如果编译好的dll在jna中提示不能找到该函数,请注意是否使用了extern “C” 关键字。或者使用dll查看器看一下

相关文章

  • jna对结构体、指针、引用、拷贝参数传递的使用

    虽然之前也用过jna,但是对于[结构体]的传递、指针参数数与返回值、引用参数与返回值、拷贝变量传递使用没有总结。 ...

  • 读书笔记17.06.02【stack】【vector】

    C++中参数传递:按值传递,指针传递和引用传递按值传递:形参是实参的拷贝。指针传递:拷贝指针,被调用函数对指针指向...

  • Go语言学习笔记(三)

    指针 Go的指针不能运算 参数传递 Go的参数传递是值传递(值传递:开辟新的空间,拷贝传递参数的值,引用传递:引用...

  • Go 面向对象编程

    struct 实例化方式 结构体语法糖 结构体是值类型 结构体 深拷贝和浅拷贝 即值传递和引用传递 匿名结构体 结...

  • iOS浅拷贝和深拷贝,copy和mutableCopy的区别

    深拷贝和浅拷贝都是针对复合类型(对象,结构体指针) 浅拷贝 新对象是拷贝了原对象的地址(引用),指向的还是原来的对...

  • Go语言学习教程(十一)

    一、结构体指针 * 由于结构体是值类型,在方法传递时希望传递结构体地址,可以使用时结构体指针完成 * 可以结合ne...

  • Java面试集锦

    1. 引用传递的问题(记住java里面是没有指针的,只有值拷贝和引用拷贝) 引用拷贝拷贝的实际是地址,当引用传递过...

  • 王道程序员求职宝典(十)函数,栈与队列

    函数 参数传递值传递指针传递引用传递指针引用*& 内联函数成员函数内联普通函数内联宏定义 默认参数从右向左设定默认...

  • 按值传递与按引用传递

    按值传递 -- 传递的是参数的值,即参数本身。 按引用传递 -- 传递的是指向参数的值的引用(指针),而不是参数的...

  • Go语言之结构体指针

    结构体本身属于值类型,可以通过指针操作结构体,编程引用类型的数据,通过new()创建指针 结构体指针

网友评论

    本文标题:jna对结构体、指针、引用、拷贝参数传递的使用

    本文链接:https://www.haomeiwen.com/subject/yipfzrtx.html