由于使用VB.net调用Fortran的DLL,没法直接调试Fortran DLL的场元计算函数,我们根本搞不清楚程序报错的问题出在哪儿。开始猜测是字符串传入的问题,用deepseek搜索了字符串传入的方法,按照它给出的方法逐一尝试都不行。

后来换了一种思路,将程序报错输入deepseek。

里面有1个调试Fortran DLL 场元函数的方法,在Fortran子程序开头添加写文件日志,确认是否进入函数,并打印接收到的参数值(尤其是字符串长度和内容),以判断是否参数传递正确。

OPEN(99, FILE='C:\debug.log', STATUS='UNKNOWN', POSITION='APPEND')
WRITE(99,*) 'Entered, x=', x, ' m=', m, ' n=', n
WRITE(99,*) 's1 length=', LEN(s1), ' s1=', s1
WRITE(99,*) 's2 length=', LEN(s2), ' s2=', s2
WRITE(99,*) 's3 length=', LEN(s3), ' s3=', s3
CLOSE(99)

如果日志没有生成,说明崩溃发生在进入子程序之前(调用约定或参数数量不匹配)。如果生成了但某些字符串长度为0或乱码,说明长度参数传递错误。

增加这段程序以后,通过日志文件,首先知道了整数传输错误,Fortran函数中整数参数传入需要加!DEC$ ATTRIBUTES VALUE::na,nb,见下图。

Fortran数据类型的定义与VB.net数据类型对应关系如下表。

整数参数传入问题解决以后,字符串参数传入也有问题。字符串参数要传递长度参数,对于多个 CHARACTER*(*) 参数,Intel Fortran将隐藏长度参数全部放在最后。

<DllImport(...)>
Public Shared Sub GGMALLELEMENTGRFD_FILE(
    ByRef x As Double,
    ByVal m As Integer,
    ByVal n As Integer,
    ByVal s1 As String, ByVal s2 As String, ByVal s3 As String,
    ByVal len_s1 As Integer, ByVal len_s2 As Integer, ByVal len_s3 As Integer
)

也就是说,在VB.net调用端需要显式添加长度参数作为函数参数,而Fortran端函数省略长度参数。

至此,问题全部解决。程序运行界面如下图。

计算结果对比见下图。

单点转换界面如下图。

章老师单点计算结果见下图。计算结果一致。

小结

很显然,deepseek已经完全替代并超过了传统搜索引擎。传统搜索引擎只能搜到文献的摘要,而deepseek能搜到内容。传统搜索引擎只能根据关键字搜索程序报错的相关内容,仅呈现而无分析,而deepseek能分析程序报错的全部内容,并能给出多种解决方案。人工智能太好用了,我们都要积极地拥抱它,用好它。

参考文献

Fortran与VB.NET的混合编程_胡文清_2017

Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐