You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java使用jniwrapper向DLL传递uint64_t类型回调指针的问题

解决jniwrapper传递回调函数指针为uint64_t类型的方案

你遇到的问题核心是第三方DLL要求将回调指针以uint64_t数值的形式存储在结构体中,而直接映射为Pointer/Void类型会传入jniwrapper封装的对象结构,不符合DLL的预期,按以下步骤操作即可解决:


步骤1:调整结构体的Java映射定义

结构体中的callback字段不要映射为Pointer/Void类型,要直接映射为jniwrapper提供的UInt64类型,和DLL的结构体定义完全对齐:

import com.jniwrapper.Structure;
import com.jniwrapper.UInt64;

public class RandomStruct extends Structure {
    // 按DLL定义的顺序添加所有其他结构体字段,此处省略
    private UInt64 callback = new UInt64();

    public RandomStruct() {
        // 按结构体实际字段的先后顺序依次注册所有字段
        // addField(其他字段1);
        addField(callback);
        // addField(其他字段2);
    }

    // 提供设置回调指针的方法
    public void setCallbackValue(long ptrValue) {
        this.callback.setValue(ptrValue);
    }
}

步骤2:定义符合DLL要求的回调类

根据DLL要求的回调签名、调用约定(stdcall/cdecl)定义对应的回调类,jniwrapper中需要继承Callback类,如果是stdcall约定还需要实现StdCallLibrary.StdCallCallback接口:

import com.jniwrapper.Callback;
import com.jniwrapper.Int;
import com.jniwrapper.win32.StdCallLibrary;

// 示例:假设DLL要求的回调签名为 void callback(int eventId),调用约定为stdcall
public class CustomCallback extends Callback implements StdCallLibrary.StdCallCallback {
    @Override
    public void run() {
        // 按DLL定义的参数顺序依次读取入参
        Int eventId = new Int();
        readParameter(eventId);
        
        // 此处编写实际的回调业务逻辑
        System.out.println("触发回调,事件ID:" + eventId.getValue());
    }
}

步骤3:获取回调原生指针并传入结构体

创建回调实例后,通过jniwrapper的API获取其原生指针的数值,再存入结构体的UInt64字段即可:

// 1. 实例化回调,必须全程持有该实例的强引用,不能被GC回收,否则指针会失效
CustomCallback myCallback = new CustomCallback();
// 2. 获取回调对应的原生指针的64位数值
long callbackPtr = myCallback.getPointer().getPeer();
// 3. 构造结构体并设置回调字段
RandomStruct struct = new RandomStruct();
struct.setCallbackValue(callbackPtr);
// 4. 后续正常将struct传递给DLL的对应调用函数即可

注意事项

  • 回调的调用约定必须和DLL要求完全匹配,否则会出现参数读取错误、程序崩溃等问题
  • 回调实例必须持有强引用,建议存为类的成员变量而非局部变量,避免Java GC回收后DLL调用野指针
  • 不需要使用回调后,手动调用myCallback.dispose()释放原生资源,避免内存泄漏

内容的提问来源于stack exchange,提问作者Jack

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.01 07:36:02