using System.Runtime.InteropServices; using FortranWebApi.Models; using System.Text.Json; using System.Runtime.InteropServices.Marshalling; using System.IO; namespace FortranWebApi.Services { public class FortranInteropService { // 静态构造函数设置DLL导入解析器 static FortranInteropService() { // 添加当前目录到库搜索路径 NativeLibrary.SetDllImportResolver(typeof(FortranInteropService).Assembly, (name, assembly, path) => { if (name == "libSUB_SHUILIANGJISUAN.so") { // 尝试从当前目录加载 string currentDir = Directory.GetCurrentDirectory(); string libraryPath = Path.Combine(currentDir, "libSUB_SHUILIANGJISUAN.so"); if (File.Exists(libraryPath)) { return NativeLibrary.Load(libraryPath); } } // 回退到默认加载行为 return IntPtr.Zero; }); } // DllImport声明 [DllImport("libSUB_SHUILIANGJISUAN.so", CallingConvention = CallingConvention.Cdecl, EntryPoint = "SUB_SHUILIANGJISUAN")] private static extern void SUB_SHUILIANGJISUAN( ref int NDATA, ref float LONG, ref int INbd, ref int INzd, ref int INsm, ref int INrough, ref float ZZ0, ref int DB, float[] UQ, float[] DQH, ref float dt, float[] OUTT, float[] OUTQ, float[] OUTH ); public string ProcessFortranRequest(string requestText) { try { // 解析请求 var options = new JsonSerializerOptions { PropertyNamingPolicy = JsonNamingPolicy.CamelCase, DictionaryKeyPolicy = JsonNamingPolicy.CamelCase, PropertyNameCaseInsensitive = true, WriteIndented = true }; var request = JsonSerializer.Deserialize(requestText, options); if (request == null) { throw new ArgumentException("无效的请求格式"); } // 准备输入参数 var parameters = request.Parameters; // 提取参数 int NDATA = GetIntParameter(parameters, "NDATA"); float LONG = GetFloatParameter(parameters, "LONG"); int INbd = GetIntParameter(parameters, "INbd"); int INzd = GetIntParameter(parameters, "INzd"); int INsm = GetIntParameter(parameters, "INsm"); int INrough = GetIntParameter(parameters, "INrough"); float ZZ0 = GetFloatParameter(parameters, "ZZ0"); int DB = GetIntParameter(parameters, "DB"); float[] UQ = GetFloatArrayParameter(parameters, "UQ"); float[] DQH = GetFloatArrayParameter(parameters, "DQH"); float dt = GetFloatParameter(parameters, "dt"); // 准备数组参数 float[] OUTT = new float[10000]; // 输出数组,初始大小为10000 float[] OUTQ = new float[10000]; // 输出数组,初始大小为10000 float[] OUTH = new float[10000]; // 输出数组,初始大小为10000 // 调用Fortran函数 SUB_SHUILIANGJISUAN( ref NDATA, ref LONG, ref INbd, ref INzd, ref INsm, ref INrough, ref ZZ0, ref DB, UQ, DQH, ref dt, OUTT, OUTQ, OUTH ); // 更新输出参数 UpdateArrayParameter(parameters, "OUTT", OUTT); UpdateArrayParameter(parameters, "OUTQ", OUTQ); UpdateArrayParameter(parameters, "OUTH", OUTH); // 处理输出数组 // 处理输出数组 OUTT // 注意:没有找到明确的长度参数,使用非零元素数量 { int nonZeroCount = 0; for (int i = 0; i < OUTT.Length; i++) { if (OUTT[i] != 0) nonZeroCount = i + 1; } if (nonZeroCount > 0) { float[] resultArray = new float[nonZeroCount]; Array.Copy(OUTT, resultArray, nonZeroCount); UpdateArrayParameter(parameters, "OUTT", resultArray); } } // 处理输出数组 OUTQ // 注意:没有找到明确的长度参数,使用非零元素数量 { int nonZeroCount = 0; for (int i = 0; i < OUTQ.Length; i++) { if (OUTQ[i] != 0) nonZeroCount = i + 1; } if (nonZeroCount > 0) { float[] resultArray = new float[nonZeroCount]; Array.Copy(OUTQ, resultArray, nonZeroCount); UpdateArrayParameter(parameters, "OUTQ", resultArray); } } // 处理输出数组 OUTH // 注意:没有找到明确的长度参数,使用非零元素数量 { int nonZeroCount = 0; for (int i = 0; i < OUTH.Length; i++) { if (OUTH[i] != 0) nonZeroCount = i + 1; } if (nonZeroCount > 0) { float[] resultArray = new float[nonZeroCount]; Array.Copy(OUTH, resultArray, nonZeroCount); UpdateArrayParameter(parameters, "OUTH", resultArray); } } // 返回结果 - 只返回原始请求的结构,但包含更新后的参数 var result = new FortranRequest { FuncName = request.FuncName, ClassName = request.ClassName, Parameters = parameters }; return JsonSerializer.Serialize(result, options); } catch (Exception ex) { return JsonSerializer.Serialize(new { error = ex.Message }); } } private float GetFloatParameter(List parameters, string name) { var param = parameters.FirstOrDefault(p => p.Name == name); if (param == null || param.Data == null) { return 0.0f; } if (param.Data is JsonElement element) { if (element.ValueKind == JsonValueKind.Number) { return element.GetSingle(); } } return Convert.ToSingle(param.Data); } private double GetDoubleParameter(List parameters, string name) { var param = parameters.FirstOrDefault(p => p.Name == name); if (param == null || param.Data == null) { return 0.0; } if (param.Data is JsonElement element) { if (element.ValueKind == JsonValueKind.Number) { return element.GetSingle(); } } return Convert.ToDouble(param.Data); } private int GetIntParameter(List parameters, string name) { var param = parameters.FirstOrDefault(p => p.Name == name); if (param == null || param.Data == null) { return 0; } if (param.Data is JsonElement element) { if (element.ValueKind == JsonValueKind.Number) { return element.GetInt32(); } } return Convert.ToInt32(param.Data); } private int[] GetIntArrayParameter(List parameters, string name) { var param = parameters.FirstOrDefault(p => p.Name == name); if (param == null || param.Data == null) { return Array.Empty(); } if (param.Data is JsonElement element && element.ValueKind == JsonValueKind.Array) { var array = new List(); foreach (var item in element.EnumerateArray()) { if (item.ValueKind == JsonValueKind.Number) { array.Add(item.GetInt32()); } } return array.ToArray(); } if (param.Data is System.Collections.IEnumerable enumerable && !(param.Data is string)) { var array = new List(); foreach (var item in enumerable) { array.Add(Convert.ToInt32(item)); } return array.ToArray(); } return Array.Empty(); } private float[] GetFloatArrayParameter(List parameters, string name) { var param = parameters.FirstOrDefault(p => p.Name == name); if (param == null || param.Data == null) { return Array.Empty(); } if (param.Data is JsonElement element && element.ValueKind == JsonValueKind.Array) { var array = new List(); foreach (var item in element.EnumerateArray()) { if (item.ValueKind == JsonValueKind.Number) { array.Add(item.GetSingle()); } } return array.ToArray(); } if (param.Data is System.Collections.IEnumerable enumerable && !(param.Data is string)) { var array = new List(); foreach (var item in enumerable) { array.Add(Convert.ToSingle(item)); } return array.ToArray(); } return Array.Empty(); } private double[] GetDoubleArrayParameter(List parameters, string name) { var param = parameters.FirstOrDefault(p => p.Name == name); if (param == null || param.Data == null) { return Array.Empty(); } if (param.Data is JsonElement element && element.ValueKind == JsonValueKind.Array) { var array = new List(); foreach (var item in element.EnumerateArray()) { if (item.ValueKind == JsonValueKind.Number) { array.Add(item.GetSingle()); } } return array.ToArray(); } if (param.Data is System.Collections.IEnumerable enumerable && !(param.Data is string)) { var array = new List(); foreach (var item in enumerable) { array.Add(Convert.ToSingle(item)); } return array.ToArray(); } return Array.Empty(); } private void UpdateParameter(List parameters, string name, object value) { var param = parameters.FirstOrDefault(p => p.Name == name); if (param != null) { param.Data = value; } } private void UpdateArrayParameter(List parameters, string name, float[] value) { var param = parameters.FirstOrDefault(p => p.Name == name); if (param != null) { param.Data = value; } } private void UpdateDoubleArrayParameter(List parameters, string name, double[] value) { var param = parameters.FirstOrDefault(p => p.Name == name); if (param != null) { param.Data = value; } } private void UpdateIntArrayParameter(List parameters, string name, int[] value) { var param = parameters.FirstOrDefault(p => p.Name == name); if (param != null) { param.Data = value; } } // 添加新的辅助方法来处理二维数组 private double[,] GetDouble2DArrayParameter(List parameters, string name, int rows, int cols) { var param = parameters.FirstOrDefault(p => p.Name == name); if (param == null || param.Data == null) { return new double[rows, cols]; } double[,] result = new double[rows, cols]; if (param.Data is JsonElement element && element.ValueKind == JsonValueKind.Array) { int index = 0; foreach (var item in element.EnumerateArray()) { if (item.ValueKind == JsonValueKind.Number) { int row = index / cols; int col = index % cols; if (row < rows && col < cols) { result[row, col] = item.GetDouble(); } index++; } } } else if (param.Data is System.Collections.IEnumerable enumerable && !(param.Data is string)) { int index = 0; foreach (var item in enumerable) { int row = index / cols; int col = index % cols; if (row < rows && col < cols) { result[row, col] = Convert.ToDouble(item); } index++; } } return result; } // 添加更新二维数组参数的方法 private void UpdateDouble2DArrayParameter(List parameters, string name, double[,] value) { var param = parameters.FirstOrDefault(p => p.Name == name); if (param != null) { // 将二维数组转换为一维数组以便于JSON序列化 int rows = value.GetLength(0); int cols = value.GetLength(1); double[] flatArray = new double[rows * cols]; for (int i = 0; i < rows; i++) { for (int j = 0; j < cols; j++) { flatArray[i * cols + j] = value[i, j]; } } param.Data = flatArray; } } // float版本 private float[,] GetFloat2DArrayParameter(List parameters, string name, int rows, int cols) { var param = parameters.FirstOrDefault(p => p.Name == name); if (param == null || param.Data == null) { return new float[rows, cols]; } float[,] result = new float[rows, cols]; if (param.Data is JsonElement element && element.ValueKind == JsonValueKind.Array) { int index = 0; foreach (var item in element.EnumerateArray()) { if (item.ValueKind == JsonValueKind.Number) { int row = index / cols; int col = index % cols; if (row < rows && col < cols) { result[row, col] = item.GetSingle(); } index++; } } } else if (param.Data is System.Collections.IEnumerable enumerable && !(param.Data is string)) { int index = 0; foreach (var item in enumerable) { int row = index / cols; int col = index % cols; if (row < rows && col < cols) { result[row, col] = Convert.ToSingle(item); } index++; } } return result; } private void UpdateFloat2DArrayParameter(List parameters, string name, float[,] value) { var param = parameters.FirstOrDefault(p => p.Name == name); if (param != null) { int rows = value.GetLength(0); int cols = value.GetLength(1); float[] flatArray = new float[rows * cols]; for (int i = 0; i < rows; i++) { for (int j = 0; j < cols; j++) { flatArray[i * cols + j] = value[i, j]; } } param.Data = flatArray; } } // int版本 private int[,] GetInt2DArrayParameter(List parameters, string name, int rows, int cols) { var param = parameters.FirstOrDefault(p => p.Name == name); if (param == null || param.Data == null) { return new int[rows, cols]; } int[,] result = new int[rows, cols]; if (param.Data is JsonElement element && element.ValueKind == JsonValueKind.Array) { int index = 0; foreach (var item in element.EnumerateArray()) { if (item.ValueKind == JsonValueKind.Number) { int row = index / cols; int col = index % cols; if (row < rows && col < cols) { result[row, col] = item.GetInt32(); } index++; } } } else if (param.Data is System.Collections.IEnumerable enumerable && !(param.Data is string)) { int index = 0; foreach (var item in enumerable) { int row = index / cols; int col = index % cols; if (row < rows && col < cols) { result[row, col] = Convert.ToInt32(item); } index++; } } return result; } private void UpdateInt2DArrayParameter(List parameters, string name, int[,] value) { var param = parameters.FirstOrDefault(p => p.Name == name); if (param != null) { int rows = value.GetLength(0); int cols = value.GetLength(1); int[] flatArray = new int[rows * cols]; for (int i = 0; i < rows; i++) { for (int j = 0; j < cols; j++) { flatArray[i * cols + j] = value[i, j]; } } param.Data = flatArray; } } } }