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

JNA调用C++ .so库时多参数传递异常问题排查

排查JNA调用C++库参数传递异常的问题

仔细看了你的代码,核心问题出在Java接口的函数签名和C++导出的函数签名完全不匹配,导致内存解析混乱,才会出现后面的mean和sd值异常。

问题根源

你的C++代码导出的是一个接收三个独立参数的函数:

extern "C" void WGevaluate( Measure m, double mean, double sd){
    WestgardInterface* lib = WestgardInterface::getInstance();
    return lib->WGevaluate( m, mean, sd);
}

它期望调用时栈上依次传入Measure对象、double类型的mean、double类型的sd。

但你的Java接口却定义了一个只接收单个结构体参数的方法:

void WGevaluateWithListOnly(WGInputs.ByValue input);

JNA会把整个WGInputs结构体的内存作为单个参数传递给C++,而C++端仍然按照“三个独立参数”的逻辑去栈上读取数据:第一个参数(Measure)刚好对应结构体里的m字段,能正常解析;但后续的mean和sd会去栈上的下一个位置读取,而这些位置的内存是未初始化的垃圾数据,所以出现了mean=0和sd=3.51276e+151的异常值。

解决方案

你有两种修正方式,选其中一种即可:

方案1:修改Java接口,匹配C++的函数签名

直接让Java接口的方法参数和C++导出函数的参数一一对应:

public interface InterfaceLibWestgard extends Library {
    // 参数顺序、类型和C++完全一致
    void WGevaluate(Measure.ByValue m, double mean, double sd);
    
    static InterfaceLibWestgard INSTANCE = (InterfaceLibWestgard) 
        Native.loadLibrary("../logic/resources/calculator/libuntitled.so", InterfaceLibWestgard.class);
}

然后在主类里直接调用这个方法:

// 初始化Measure和Date的代码不变
InterfaceLibWestgard.INSTANCE.WGevaluate(m, 7.5, 4d);

方案2:修改C++导出函数,接收结构体参数

如果你想保持Java端传递结构体的方式,需要修改C++的代码,让导出函数接收一个包含三个成员的结构体:

  1. 先在C++里定义对应的结构体:
// 注意结构体的成员顺序要和Java的WGInputs完全一致
struct WGInputs {
    Measure m;
    double mean;
    double sd;
};
  1. 修改导出函数:
extern "C" void WGevaluateWithListOnly(WGInputs input){
    WestgardInterface* lib = WestgardInterface::getInstance();
    lib->WGevaluate( input.m, input.mean, input.sd);
}

这样Java端的现有接口和调用逻辑就不需要修改了。

额外注意事项

除了函数签名,还要确保Measure和Date的JNA结构体映射完全匹配C++的内存布局:

  • Java结构体的字段顺序必须和C类/结构体的成员顺序完全一致(比如C的Measure里如果先有valeur,再有date,Java的Measure结构体也要保持这个顺序)
  • 字段类型要一一对应(C++的int对应Java的int,double对应double)
  • 如果C++代码用了特殊的内存对齐(比如#pragma pack),需要在Java结构体上添加@Structure.FieldOrder注解并设置对齐方式,避免内存偏移错误。

内容的提问来源于stack exchange,提问作者Charles Socié

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 06:52:09