动态库名称调整

This commit is contained in:
2025-08-01 10:47:59 +08:00
parent 7c1b07feba
commit 7731d92b1e
4 changed files with 209 additions and 59 deletions

View File

@@ -0,0 +1,132 @@
package com.njcn.advance.event.cause.jna;
import com.sun.jna.Library;
import com.sun.jna.Native;
import com.sun.jna.Structure;
import java.io.*;
import java.util.Arrays;
import java.util.List;
/**
* JNA接口调用qvvr_dll.dll
*/
public interface QvvrCauseDLL extends Library {
/**
* 加载DLL - 从resource目录或classpath
*/
QvvrCauseDLL INSTANCE = loadLibrary();
/**
* 支持jar打包的库加载方法 - 从jar内resources提取到临时目录后加载
*/
static QvvrCauseDLL loadLibrary() {
String osName = System.getProperty("os.name").toLowerCase();
String libFileName;
String resourcePath;
// 根据操作系统确定库文件名
if (osName.contains("windows")) {
libFileName = "qvvr_cause_dll.dll";
resourcePath = "/qvvr_cause_dll.dll";
} else if (osName.contains("linux")) {
libFileName = "libqvvr_cause_dll.so";
resourcePath = "/libqvvr_cause_dll.so";
} else {
throw new UnsupportedOperationException("不支持的操作系统: " + osName);
}
try {
// 从jar中提取库文件到临时目录
File tempLibFile = extractLibraryFromJar(resourcePath, libFileName);
// 加载提取的库文件
System.out.println("加载库文件: " + tempLibFile.getAbsolutePath());
return Native.load(tempLibFile.getAbsolutePath(), QvvrCauseDLL.class);
} catch (Exception e) {
throw new RuntimeException(
"无法加载QVVR库文件。\n" +
"请确保文件 " + libFileName + " 存在于 src/main/resources/ 目录下。\n" +
"当前操作系统: " + osName,
e
);
}
}
/**
* 从jar中提取库文件到临时目录
*/
static File extractLibraryFromJar(String resourcePath, String libFileName) throws IOException {
// 获取资源输入流
InputStream libStream = QvvrCauseDLL.class.getResourceAsStream(resourcePath);
if (libStream == null) {
throw new FileNotFoundException("在jar中找不到库文件: " + resourcePath);
}
// 创建临时文件
String tempDir = System.getProperty("java.io.tmpdir");
File tempLibFile = new File(tempDir, "qvvr_" + System.currentTimeMillis() + "_" + libFileName);
// 提取库文件到临时目录
try (FileOutputStream out = new FileOutputStream(tempLibFile)) {
byte[] buffer = new byte[8192];
int bytesRead;
while ((bytesRead = libStream.read(buffer)) != -1) {
out.write(buffer, 0, bytesRead);
}
} finally {
libStream.close();
}
// 设置为可执行
tempLibFile.setExecutable(true);
tempLibFile.setReadable(true);
// JVM退出时删除临时文件
tempLibFile.deleteOnExit();
System.out.println("已提取库文件到: " + tempLibFile.getAbsolutePath());
return tempLibFile;
}
/**
* 直接调用C DLL的qvvr_fun_cause函数
* void __stdcall qvvr_fun_cause(void *data)
*/
void qvvr_fun_cause(QvvrDataStruct data);
/**
* 对应C语言的qvvr_data_struct结构体
* 完全按照qvvr_dll.h中的定义映射
*/
public static class QvvrDataStruct extends Structure {
// 输入参数定义
public float[] smp_va = new float[128 * 50 * 120]; // A相电压采样数据
public float[] smp_vb = new float[128 * 50 * 120]; // B相电压采样数据
public float[] smp_vc = new float[128 * 50 * 120]; // C相电压采样数据
public int smp_rate; // 采样率参数
public int smp_len; // 每个通道的采样数据个数
// 输入阈值参数
public float[] threshold = new float[50]; // 预设阈值时间参数
// 输出结果参数定义
public int cause; // 电压暂降判断出暂降原因 0-未知,1-短路,2-电压调节器,3-感动电机
public int no_cal; // 未计算判断标志该位1表示输入数据有问题数据缺失或异常等未进行电压暂降判断暂降原因
@Override
protected List<String> getFieldOrder() {
return Arrays.asList("smp_va", "smp_vb", "smp_vc", "smp_rate", "smp_len", "threshold", "cause", "no_cal");
}
public QvvrDataStruct() {
super();
// 初始化输出参数
this.cause = 0;
this.no_cal = 0;
}
}
}

View File

@@ -1,6 +1,7 @@
package com.njcn.advance.event.service; package com.njcn.advance.event.service;
import com.njcn.advance.event.cause.core.VoltageSagAnalyzer; import com.njcn.advance.event.cause.core.VoltageSagAnalyzer;
import com.njcn.advance.event.cause.jna.QvvrCauseDLL;
import com.njcn.advance.event.cause.model.AnalysisResult; import com.njcn.advance.event.cause.model.AnalysisResult;
import com.njcn.advance.event.cause.model.DataFeature; import com.njcn.advance.event.cause.model.DataFeature;
import com.njcn.advance.event.cause.model.QvvrDataStruct; import com.njcn.advance.event.cause.model.QvvrDataStruct;
@@ -30,7 +31,7 @@ public class Test {
WaveFileComponent waveFileComponent = new WaveFileComponent(); WaveFileComponent waveFileComponent = new WaveFileComponent();
EventAnalysisDTO eventAnalysis = new EventAnalysisDTO(); EventAnalysisDTO eventAnalysis = new EventAnalysisDTO();
WaveDataDTO waveDataDTO; WaveDataDTO waveDataDTO;
String waveName = "5"; String waveName = "11";
String cfgPath, datPath; String cfgPath, datPath;
cfgPath = "D:\\comtrade\\00-B7-8D-00-FA-44" + File.separator + waveName + GeneralConstant.CFG; cfgPath = "D:\\comtrade\\00-B7-8D-00-FA-44" + File.separator + waveName + GeneralConstant.CFG;
datPath = "D:\\comtrade\\00-B7-8D-00-FA-44" + File.separator + waveName + GeneralConstant.DAT; datPath = "D:\\comtrade\\00-B7-8D-00-FA-44" + File.separator + waveName + GeneralConstant.DAT;
@@ -41,34 +42,64 @@ public class Test {
throw new BusinessException(WaveFileResponseEnum.ANALYSE_WAVE_NOT_FOUND); throw new BusinessException(WaveFileResponseEnum.ANALYSE_WAVE_NOT_FOUND);
} }
waveDataDTO = waveFileComponent.getComtrade(cfgStream, datStream, 0); waveDataDTO = waveFileComponent.getComtrade(cfgStream, datStream, 0);
// // java针对暂降原因分析的调用
// QvvrDataStruct qvvrDataStruct = new QvvrDataStruct();
// // 采样率
// qvvrDataStruct.setSmpRate(waveDataDTO.getComtradeCfgDTO().getFinalSampleRate());
// // 瞬时值
// List<List<Float>> listWaveData = waveDataDTO.getListWaveData();
// // 通道采样个数
// qvvrDataStruct.setSmpLen(listWaveData.size());
// // 获取ABC三相的瞬时数据
// // A相电压采样数据
// float[] smpVa = new float[listWaveData.size()];
// // B相电压采样数据
// float[] smpVb = new float[listWaveData.size()];
// // C相电压采样数据
// float[] smpVc = new float[listWaveData.size()];
// for (int i = 0; i < listWaveData.size(); i++) {
// smpVa[i] = listWaveData.get(i).get(1);
// smpVb[i] = listWaveData.get(i).get(2);
// smpVc[i] = listWaveData.get(i).get(3);
// }
// qvvrDataStruct.setSmpVa(smpVa);
// qvvrDataStruct.setSmpVb(smpVb);
// qvvrDataStruct.setSmpVc(smpVc);
//
// // 暂降原因
// VoltageSagAnalyzer voltageSagAnalyzer = new VoltageSagAnalyzer();
// try{
// AnalysisResult cause = voltageSagAnalyzer.analyzeVoltageSagWithDetails(qvvrDataStruct);
// eventAnalysis.setCause(cause.getCause());
// }catch (Exception e){
// log.error("DAT文件分析异常", e);
// eventAnalysis.setCause(DataFeature.CAUSE_TYPE0);
// eventAnalysis.setCauseFlag(0);
// }
QvvrDataStruct qvvrDataStruct = new QvvrDataStruct();
// 采样率
qvvrDataStruct.setSmpRate(waveDataDTO.getComtradeCfgDTO().getFinalSampleRate());
// 瞬时值
List<List<Float>> listWaveData = waveDataDTO.getListWaveData(); List<List<Float>> listWaveData = waveDataDTO.getListWaveData();
// 通道采样个数
qvvrDataStruct.setSmpLen(listWaveData.size());
// 获取ABC三相的瞬时数据
// A相电压采样数据
float[] smpVa = new float[listWaveData.size()];
// B相电压采样数据
float[] smpVb = new float[listWaveData.size()];
// C相电压采样数据
float[] smpVc = new float[listWaveData.size()];
for (int i = 0; i < listWaveData.size(); i++) {
smpVa[i] = listWaveData.get(i).get(1);
smpVb[i] = listWaveData.get(i).get(2);
smpVc[i] = listWaveData.get(i).get(3);
}
qvvrDataStruct.setSmpVa(smpVa);
qvvrDataStruct.setSmpVb(smpVb);
qvvrDataStruct.setSmpVc(smpVc);
VoltageSagAnalyzer voltageSagAnalyzer = new VoltageSagAnalyzer();
AnalysisResult cause = voltageSagAnalyzer.analyzeVoltageSagWithDetails(qvvrDataStruct);
log.info("DAT文件分析结果: 原因={} ({})", cause.getCause(), getCauseDescription(cause.getCause()));
// 暂降原因JNA的方式
com.njcn.advance.event.cause.jna.QvvrCauseDLL.QvvrDataStruct causeDataStruct = new com.njcn.advance.event.cause.jna.QvvrCauseDLL.QvvrDataStruct();
causeDataStruct.smp_rate = waveDataDTO.getComtradeCfgDTO().getFinalSampleRate();
causeDataStruct.smp_len = listWaveData.size();
// 获取ABC三相的瞬时数据
for (int i = 0; i < listWaveData.size(); i++) {
causeDataStruct.smp_va[i] = listWaveData.get(i).get(1);
causeDataStruct.smp_vb[i] = listWaveData.get(i).get(2);
causeDataStruct.smp_vc[i] = listWaveData.get(i).get(3);
}
// 执行算法分析 - 直接调用C DLL
try {
QvvrCauseDLL.INSTANCE.qvvr_fun_cause(causeDataStruct);
System.out.println("暂降原因: " + getCauseDescription(causeDataStruct.cause));
} catch (Exception e) {
System.err.println("调用DLL失败: " + e.getMessage());
e.printStackTrace();
}
// 暂降类型JNA的方式
// 创建数据结构 // 创建数据结构
com.njcn.advance.event.type.jna.QvvrDLL.QvvrDataStruct typeDataStruct = new com.njcn.advance.event.type.jna.QvvrDLL.QvvrDataStruct(); com.njcn.advance.event.type.jna.QvvrDLL.QvvrDataStruct typeDataStruct = new com.njcn.advance.event.type.jna.QvvrDLL.QvvrDataStruct();
typeDataStruct.smp_rate = waveDataDTO.getComtradeCfgDTO().getFinalSampleRate(); typeDataStruct.smp_rate = waveDataDTO.getComtradeCfgDTO().getFinalSampleRate();

View File

@@ -2,6 +2,7 @@ package com.njcn.advance.event.service.impl;
import cn.hutool.core.util.StrUtil; import cn.hutool.core.util.StrUtil;
import com.njcn.advance.event.cause.core.VoltageSagAnalyzer; import com.njcn.advance.event.cause.core.VoltageSagAnalyzer;
import com.njcn.advance.event.cause.jna.QvvrCauseDLL;
import com.njcn.advance.event.cause.model.AnalysisResult; import com.njcn.advance.event.cause.model.AnalysisResult;
import com.njcn.advance.event.cause.model.DataFeature; import com.njcn.advance.event.cause.model.DataFeature;
import com.njcn.advance.event.cause.model.QvvrDataStruct; import com.njcn.advance.event.cause.model.QvvrDataStruct;
@@ -88,36 +89,26 @@ public class EventAdvanceServiceImpl implements IEventAdvanceService {
} }
} }
QvvrDataStruct qvvrDataStruct = new QvvrDataStruct();
// 采样率
qvvrDataStruct.setSmpRate(waveDataDTO.getComtradeCfgDTO().getFinalSampleRate());
// 瞬时值
List<List<Float>> listWaveData = waveDataDTO.getListWaveData(); List<List<Float>> listWaveData = waveDataDTO.getListWaveData();
// 通道采样个数
qvvrDataStruct.setSmpLen(listWaveData.size());
// 获取ABC三相的瞬时数据
// A相电压采样数据
float[] smpVa = new float[listWaveData.size()];
// B相电压采样数据
float[] smpVb = new float[listWaveData.size()];
// C相电压采样数据
float[] smpVc = new float[listWaveData.size()];
for (int i = 0; i < listWaveData.size(); i++) {
smpVa[i] = listWaveData.get(i).get(1);
smpVb[i] = listWaveData.get(i).get(2);
smpVc[i] = listWaveData.get(i).get(3);
}
qvvrDataStruct.setSmpVa(smpVa);
qvvrDataStruct.setSmpVb(smpVb);
qvvrDataStruct.setSmpVc(smpVc);
// 暂降原因 // 暂降原因JNA的方式
VoltageSagAnalyzer voltageSagAnalyzer = new VoltageSagAnalyzer(); com.njcn.advance.event.cause.jna.QvvrCauseDLL.QvvrDataStruct causeDataStruct = new com.njcn.advance.event.cause.jna.QvvrCauseDLL.QvvrDataStruct();
try{ causeDataStruct.smp_rate = waveDataDTO.getComtradeCfgDTO().getFinalSampleRate();
AnalysisResult cause = voltageSagAnalyzer.analyzeVoltageSagWithDetails(qvvrDataStruct); causeDataStruct.smp_len = listWaveData.size();
eventAnalysis.setCause(cause.getCause()); // 获取ABC三相的瞬时数据
}catch (Exception e){ for (int i = 0; i < listWaveData.size(); i++) {
log.error("DAT文件分析异常", e); causeDataStruct.smp_va[i] = listWaveData.get(i).get(1);
causeDataStruct.smp_vb[i] = listWaveData.get(i).get(2);
causeDataStruct.smp_vc[i] = listWaveData.get(i).get(3);
}
// 执行算法分析 - 直接调用C DLL
try {
QvvrCauseDLL.INSTANCE.qvvr_fun_cause(causeDataStruct);
eventAnalysis.setCause(causeDataStruct.cause);
if (causeDataStruct.no_cal != 0) {
eventAnalysis.setCauseFlag(0);
}
} catch (Exception e) {
eventAnalysis.setCause(DataFeature.CAUSE_TYPE0); eventAnalysis.setCause(DataFeature.CAUSE_TYPE0);
eventAnalysis.setCauseFlag(0); eventAnalysis.setCauseFlag(0);
} }
@@ -157,7 +148,6 @@ public class EventAdvanceServiceImpl implements IEventAdvanceService {
} catch (Exception e) { } catch (Exception e) {
eventAnalysis.setType(DataFeature.TYPE10); eventAnalysis.setType(DataFeature.TYPE10);
eventAnalysis.setTypeFlag(0); eventAnalysis.setTypeFlag(0);
e.printStackTrace();
} }
return eventAnalysis; return eventAnalysis;
} }

View File

@@ -31,11 +31,8 @@ public interface QvvrDLL extends Library {
libFileName = "qvvr_dll.dll"; libFileName = "qvvr_dll.dll";
resourcePath = "/qvvr_dll.dll"; resourcePath = "/qvvr_dll.dll";
} else if (osName.contains("linux")) { } else if (osName.contains("linux")) {
libFileName = "libqvvr.so"; libFileName = "libqvvr_dll.so";
resourcePath = "/libqvvr.so"; resourcePath = "/libqvvr_dll.so";
} else if (osName.contains("mac")) {
libFileName = "libqvvr.dylib";
resourcePath = "/libqvvr.dylib";
} else { } else {
throw new UnsupportedOperationException("不支持的操作系统: " + osName); throw new UnsupportedOperationException("不支持的操作系统: " + osName);
} }