将FORTRAN DLLIMPORT翻译成C++;/C#
在我目前的工作中,一项主要任务是使用现有的工程工具,并对其进行更新,因为它已经停止在现代操作系统上工作 现在,该工具是用FORTRAN编写的,并且大多数源文件头都表示如下内容:将FORTRAN DLLIMPORT翻译成C++;/C#,c#,fortran,dllimport,C#,Fortran,Dllimport,在我目前的工作中,一项主要任务是使用现有的工程工具,并对其进行更新,因为它已经停止在现代操作系统上工作 现在,该工具是用FORTRAN编写的,并且大多数源文件头都表示如下内容: C modified by (obfuscated) at dd. mm. 19yy to do something 从那时起,员工们就开始骑自行车,很多文档要么从未完成,要么已经丢失。因此,我们需要破译程序是如何运行的,然后用更现代的语言重新创建该功能 为此,我们选择了C 我有点能读FORTRAN,所以到目前为
C modified by (obfuscated) at dd. mm. 19yy to do something
从那时起,员工们就开始骑自行车,很多文档要么从未完成,要么已经丢失。因此,我们需要破译程序是如何运行的,然后用更现代的语言重新创建该功能
为此,我们选择了C
我有点能读FORTRAN,所以到目前为止,破解数学和逻辑都是直截了当的,但说到dllimports,我就卡住了
我不知道谁制作了dll,也不知道源代码在哪里,但我确定的是,他们负责我们一些供应商组件的一些关键计算。因此,我不能简单地用新代码替换dll,因为我不知道其中包含哪些等式
我发现旧程序将xml格式的数据发送到dll条目,并返回一个类似xml的字符串。然而,我无法复制它,因为我不完全确定它是如何工作的
可以解释这个,或者甚至把它转换成C++ +C等价物?< /P>
! interface for CalculateStuff.dll
INTERFACE
SUBROUTINE CalculateComponent(Input, Output)
!DEC$ ATTRIBUTES REFERENCE, ALIAS : '_CC@16' :: CalculateComponent
!DEC$ ATTRIBUTES DLLIMPORT :: CalculateStuff
CHARACTER*(*) Input, Output
!DEC$ ATTRIBUTES REFERENCE :: Input
!DEC$ ATTRIBUTES REFERENCE :: Output
END SUBROUTINE
END INTERFACE
目前我有这段代码(C#),但似乎对我来说失败了:
class CalculateStuff{
[DllImport("CalculateStuff.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall, EntryPoint = "_CC@16")]
public static extern void CalculateComponent(ref string input, ref string output);
}
编辑1:添加了字符集
现在程序给了我一个例外,我认为这是一个进步:
An attempt was made to load a program with an incorrect format. (Exception from HRESULT: 0x8007000B)
编辑2:重新编译为32位应用程序,现在我得到:
External component has thrown an exception.
编辑3:将返回类型更改为void,因为这对我来说完全有意义
编辑4:添加了定义为stdCall的调用约定,因为许多评论暗示它没有帮助。
还尝试将参数类型定义为
string
,或ref string
没有任何变化。Fortran可能对字符串的编码与C#不同。将CharSet=CharSet.Ansi
添加到DllImport
是否有帮助?还有,它是如何失败的?嗯,dll响应是空的。还将尝试设置字符集:)还有可以应用于每个参数的marshallas
属性,这提供了更多的自定义可能性。我还猜测这两个参数中的任何一个都必须是ref
。此外,由于它是一个子程序,因此没有返回值,因此我还猜测C#函数应该是void
。如果您有旧的MSDN订阅磁盘,它们可能仍然有Powerstation 5,其中将有描述使用的手册!MS$,与相同!12美元。这里发生了一些事情。第一个是DLL例程,正如其他人所说,使用STDCALL调用机制,有一种C#方法来指定,但我不确定它是什么。另一个是字符串长度。在这里,您必须知道哪个编译器构建了DLL,因为长度可能紧跟在字符串地址之后,也可能在末尾。我的猜测是,它们将遵循地址,因为这是DEC/Compaq(和MS)约定,如果DLL是使用Intel Visual Fortran构建的,那么长度可能会在末尾。Fortran对字符串的编码可能与C#不同。将CharSet=CharSet.Ansi
添加到DllImport
是否有帮助?还有,它是如何失败的?嗯,dll响应是空的。还将尝试设置字符集:)还有可以应用于每个参数的marshallas
属性,这提供了更多的自定义可能性。我还猜测这两个参数中的任何一个都必须是ref
。此外,由于它是一个子程序,因此没有返回值,因此我还猜测C#函数应该是void
。如果您有旧的MSDN订阅磁盘,它们可能仍然有Powerstation 5,其中将有描述使用的手册!MS$,与相同!12美元。这里发生了一些事情。第一个是DLL例程,正如其他人所说,使用STDCALL调用机制,有一种C#方法来指定,但我不确定它是什么。另一个是字符串长度。在这里,您必须知道哪个编译器构建了DLL,因为长度可能紧跟在字符串地址之后,也可能在末尾。我的猜测是,它们将遵循地址,因为这是DEC/Compaq(和MS)约定,如果DLL是使用Intel Visual Fortran构建的,那么长度可能会在末尾。Fortran对字符串的编码可能与C#不同。将CharSet=CharSet.Ansi
添加到DllImport
是否有帮助?还有,它是如何失败的?嗯,dll响应是空的。还将尝试设置字符集:)还有可以应用于每个参数的marshallas
属性,这提供了更多的自定义可能性。我还猜测这两个参数中的任何一个都必须是ref
。此外,由于它是一个子程序,因此没有返回值,因此我还猜测C#函数应该是void
。如果您有旧的MSDN订阅磁盘,它们可能仍然有Powerstation 5,其中将有描述使用的手册!MS$,与相同!12美元。这里发生了一些事情。第一个是DLL例程,正如其他人所说,使用STDCALL调用机制,有一种C#方法来指定,但我不确定它是什么。另一个是字符串长度。在这里,您必须知道哪个编译器构建了DLL,因为长度可能紧跟在字符串地址之后,也可能在末尾。我的猜测是,它们将遵循地址,因为这是DEC/Compaq(和MS)约定,如果DLL是使用Intel Visual Fortran构建的,那么长度可能在末尾。