You need to enable JavaScript to run this app. C#调用Fortran DLL时如何实现跨类公开访问的double指针并避免未初始化报错
优惠活动
大模型
产品
解决方案
定价
更多

C#调用Fortran DLL时如何实现跨类公开访问的double指针并避免未初始化报错

报错翻译

你遇到的类顶层指针未初始化的英文报错,对应中文含义如下:

  • 若为静态方法访问非静态字段触发的报错:CS0120: 需要对非静态字段、方法或属性“cshare_call2fortran.ptr_spf”的对象引用
  • 若为指针未赋值触发的使用错误:CS0165: 使用了未赋值的变量“ptr_spf”
解决步骤
  • 项目前置配置:打开项目属性 → 生成选项卡,勾选允许不安全代码,否则C#不支持声明非托管指针类型。
  • 类字段调整:在cshare_call2fortran类顶层声明静态、显式初始化的指针字段,替代原局部变量逻辑:
class cshare_call2fortran {
    // 原有静态List可按需保留做备份,不需要可直接删除
    public static List<double> SPFlowValues = new List<double>();
    // 公开静态指针,显式初始化为null避免未初始化报错
    public unsafe static double* ptr_spf = null;
    // 缓存数组长度,避免重复查询Fortran端形状
    public static int spflow_len = 0;

    // 其余原有DllImport声明、工具方法逻辑保持不变
    // ...
}
  • 修改get_spflow_ptr方法,直接给类级指针赋值:
public static void get_spflow_ptr()
{
    int index_spf = individual_varnames.FindIndex(x => x.Contains("INFLOW"));
    var SPFlow_Address = Encoding.ASCII.GetBytes(individual_varnames[index_spf] + char.MinValue);

    int rank_spf = 0;
    result = get_var_rank(SPFlow_Address, ref rank_spf);
    var shape_spf = new int[rank_spf];
    result = get_var_shape(SPFlow_Address, shape_spf);
    spflow_len = shape_spf[0]; // 缓存数组长度
    
    unsafe
    {
        // 直接给类级ptr_spf赋值,不再声明局部指针变量
        result = get_value_ptr_double(SPFlow_Address, ref ptr_spf);
        // 可选:需要缓存旧值时保留以下遍历逻辑
        // for (int i = 0; i < spflow_len; ++i)
        // {
        //     SPFlowValues.Add(ptr_spf[i]);
        // }
    }
}
实时访问方法

其他类需要获取Fortran端实时更新的数值时,直接通过cshare_call2fortran.ptr_spf[i]读取即可。该指针直接指向Fortran端管理的内存区域,只要Fortran端未释放该块内存、未改变对应变量的指向,读取到的就是最新的数值,无需重新拷贝。

注意事项
  • 必须先成功执行get_spflow_ptr完成指针初始化后,再跨类访问该指针,否则指针为null会触发非法内存访问异常。
  • 该指针指向的内存完全由Fortran DLL管理,禁止在C#侧手动释放、修改该内存块的地址属性,避免Fortran端运行崩溃。
  • 读取数组元素前建议通过缓存的spflow_len校验索引合法性,避免越界访问。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.11.08 23:15:03