Java JNA 调用DLL(动态连接库) 回调函数

参考连接

我创建的文件如下 myObject.h

#pragma once  //规定只编译一次

//宏定义,增加可读性
#define DATAEXCHANGEDLL_API __declspec(dllexport)

//按C进行编译,声明.cpp中的函数
// typedef void(*ccback)(char *name, int length);
// 定义了一个指向函数的指针F,其指向的函数的返回值为 void 类型,参数是后面的(int).

// 此函数是被定义为回调函数,在myObject.cpp里面是没有实现的;
typedef void(*ccback)(char *name, int length, BYTE cmd, void* responseData);

extern "C" DATAEXCHANGEDLL_API int dllFunction(char *ip, int port, void (*ccback)(char *name, int length, BYTE cmd, void* responseData));

extern "C" DATAEXCHANGEDLL_API bool  test_open(void* responseData);

myObject.cpp如下

#include "pch.h"    //必要的头文件
#include "myObject.h" //自己的头文件
#include

ccback c;

int dllFunction(char *ip, int port, void(*ccback)(char *name, int length, BYTE cmd, void* responseData)) {
    printf("port is : %d\n", port);
    c = ccback;

    static int a = 5;
    int* pi = &a;

    BYTE b{ 42 };

    c(ip, port, b, pi);
    return 0;
}

bool test_open(void* responseData) {

    static int a = 5;
    int* pi = &a;
    responseData = pi;
    return 1;
}

Maven 地址


    net.java.dev.jna
    jna
    5.7.0

    cn.hutool
    hutool-all
    5.8.10

Java代码

package com.test.jnacallback;

import com.sun.jna.Callback;
import com.sun.jna.Library;
import com.sun.jna.Native;
import com.sun.jna.Pointer;
import com.sun.jna.ptr.PointerByReference;
import com.sun.jna.win32.StdCallLibrary;

/**
 * @ClassName: DllCallBackTest
 * @Author:
 * @Date: 2022/12/09
 * @Description:
 *
 *
 *          JNA中回调的本质是一个指向native函数的指针,通过这个指针可以调用native函数中的方法
 *
 *
 */

public class DllCallBackTest {

    public interface JnaCallBackDll extends StdCallLibrary {

        public static JnaCallBackDll instance = Native.load("E:\\VS项目\\javaDllTest006_Callback\\x64\\Debug\\javaDllTest006_Callback.dll",JnaCallBackDll.class);

        int dllFunction(String host, int port, Callback callback);

        Boolean test_open(PointerByReference pointer);

        public interface SCBack extends Callback {
            public void MessageHandle(String name, int length,Byte cmd, String pointer);
        }

        public static class SCBack_Impl implements SCBack {

            private PointerByReference pointerTTT = new PointerByReference(Pointer.NULL);

            @Override
            public void MessageHandle(String ip, int port, Byte cmd, String pointer) {

                // TODO Auto-generated method stub

                System.out.println("回调成功!");
                System.out.println("ip :" + ip);
                System.out.println("port :" + port);
                System.out.println("pointer :" + pointer);
                System.out.println("cmd :" + cmd);

                // 此处添加需要的数据处理操作

            }

        }

    }

    public static void main(String[] args) {
       DllCallBackTest.JnaCallBackDll.SCBack callback = new JnaCallBackDll.SCBack_Impl();
       JnaCallBackDll.instance.dllFunction("127.0.0.1", 3306, callback);

    }

}
回调成功!
ip :127.0.0.1
port :3306
pointer :
cmd :42
port is : 3306
Disconnected from the target VM, address: '127.0.0.1:51404', transport: 'socket'

Process finished with exit code 0

写在最后,如果回调函数返回的对象有类对象,像Student这种对象;需要在java中新建Student对象;

Java对应C++结构体对象

package com.test.jnacallback;

import com.sun.jna.Structure;

import java.util.Arrays;
import java.util.List;

/**
 * @ClassName: Student
 * @Author:
 * @Date: 2022/12/16
 * @Description: TODO
 */

public class Student extends Structure {

    public byte[] id = new byte[64];

    public int age;

    public int name;

    @Override
    protected List getFieldOrder() {
        return Arrays.asList(new String[]{"id","age","name"});
    }

    public byte[] getId() {
        return id;
    }

    public void setId(byte[] id) {
        this.id = id;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public int getName() {
        return name;
    }

    public void setName(int name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return "Student{" +
                "id=" + Arrays.toString(id) +
                ", age=" + age +
                ", name=" + name +
                '}';
    }
}

然后,把回调函数中的 MessageHandle 参数直接替换成对象 Student student 就行;

折腾了两三天,终于能调用通了;希望对你有帮助;具体问题具体分析把,精力有限,先写这么多,有问题留言;

Original: https://blog.csdn.net/qq_38593865/article/details/128346169
Author: lu5211019
Title: Java JNA 调用DLL(动态连接库) 回调函数

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/723272/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球