我正在尝试让 flutter 应用程序从 .mat 文件中读取 1xN 矩阵,然后使用独立的 matlab 应用程序处理这些数据,因此当我尝试实现应用程序在某个时刻失去连接时
MATLAB 函数:
function results = singleRVAnalysis(sample, numBins)
% SINGLE_RVANALYSIS Analyzes a single random variable sample
%
% Inputs:
% sample - Array of sample data
% numBins - Number of bins for histogram (default: 50)
%
% Outputs:
% results - A structure containing PDF, CDF, mean, variance, and third moment
if nargin < 2
numBins = 50;
end
edges = linspace(min(sample), max(sample), numBins + 1);
counts = histcounts(sample, edges);
binWidth = diff(edges);
pdf = counts / (sum(counts) * binWidth(1));
cdf = cumsum(pdf) * binWidth(1);
binCenters = edges(1:end-1) + diff(edges) / 2;
meanValue = sum(binCenters .* pdf * binWidth(1));
varianceValue = sum(((binCenters - meanValue).^2) .* pdf * binWidth(1));
thirdMomentValue = sum(((binCenters - meanValue).^3) .* pdf * binWidth(1));
results = struct;
results.PDF = pdf;
results.CDF = cdf;
results.Mean = meanValue;
results.Variance = varianceValue;
results.ThirdMoment = thirdMomentValue;
results.Edges = edges;
end
颤振代码:
import 'dart:ffi';
import 'dart:io';
import 'package:ffi/ffi.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:file_picker/file_picker.dart';
const String dllPath = 'lib\\SingleRVAnalysis\\SingleRVAnalysisLib.dll';
final DynamicLibrary singleRVAnalysisLib = DynamicLibrary.open(dllPath);
final class Results extends Struct {
external Pointer<Double> pdf;
external Pointer<Double> cdf;
@Double()
external double mean;
@Double()
external double variance;
@Double()
external double thirdMoment;
external Pointer<Double> edges;
@Int32()
external int binCount;
}
typedef SingleRVAnalysisNative = Results Function(
Pointer<Double>, Int32, Int32);
typedef SingleRVAnalysisDart = Results Function(Pointer<Double>, int, int);
final singleRVAnalysis = singleRVAnalysisLib.lookupFunction<
SingleRVAnalysisNative, SingleRVAnalysisDart>('mlxSingleRVAnalysis');
enum FileProcessStatus { idle, processing, completed, failed }
class FileProcessCubit extends Cubit<Map<String, dynamic>> {
FileProcessCubit() : super({'status': FileProcessStatus.idle, 'file': null});
void pickFile() async {
try {
final result = await FilePicker.platform.pickFiles();
if (result != null && result.files.single.path != null) {
emit({
'status': FileProcessStatus.processing,
'file': result.files.single,
});
await processFile(result.files.single);
} else {
emit({
'status': FileProcessStatus.failed,
'error': 'No file selected',
});
}
} catch (e) {
emit({
'status': FileProcessStatus.failed,
'error': 'File picking error: $e',
});
}
}
Future<void> processFile(PlatformFile file) async {
final filePath = file.path;
if (filePath == null) {
emit({
'status': FileProcessStatus.failed,
'error': 'No file path available',
});
return;
}
try {
final content = await File(filePath).readAsBytes();
if (content.isEmpty) {
throw Exception('The file is empty.');
}
final List<double> sample = content
.toString()
.replaceAll(RegExp(r'[^\d\.\-eE, ]'), '')
.split(RegExp(r'[,\s]+'))
.where((e) => e.isNotEmpty)
.map((e) => double.tryParse(e) ?? 0.0)
.toList();
if (sample.isEmpty) {
throw Exception('Sample array is empty.');
}
const int numBins = 50;
final Pointer<Double> samplePointer = listToPointerDouble(sample);
final result = singleRVAnalysis(samplePointer, sample.length, numBins);
try {
final pdf = result.pdf.asTypedList(numBins).toList();
final cdf = result.cdf.asTypedList(numBins).toList();
final mean = result.mean;
final variance = result.variance;
final thirdMoment = result.thirdMoment;
emit({
'status': FileProcessStatus.completed,
'mean': mean,
'variance': variance,
'thirdMoment': thirdMoment,
'pdf': pdf,
'cdf': cdf,
});
} catch (e) {
emit({
'status': FileProcessStatus.failed,
'error': 'Error during DLL processing: $e',
});
} finally {
calloc.free(samplePointer);
}
} catch (e) {
emit({
'status': FileProcessStatus.failed,
'error': 'Processing failed: $e',
});
}
}
void reset() {
emit({'status': FileProcessStatus.idle, 'file': null});
}
}
Pointer<Double> listToPointerDouble(List<double> sample) {
final Pointer<Double> pointer =
calloc.allocate<Double>(sample.length, alignment: 8);
for (int i = 0; i < sample.length; i++) {
pointer[i] = sample[i];
}
return pointer;
}
它应该分配样本指针,然后将其传递给函数以返回结果,但它在分配样本指针时的某个时刻崩溃了
尝试像这样修改你的 dart 代码:
Pointer<Double> listToPointerDouble(List<double> sample) {
final Pointer<Double> pointer =
calloc.allocate<Double>(sample.length, alignment: 8);
final nativeSamples = pointer.asTypedList(sample.length);
nativeSamples.setAll(0, sample);
return pointer.cast<Double>();
}
不要忘记在不需要后释放你的内存。
calloc.free(pointer);