前提:我正在编写符合行业标准接口/功能签名的插件DLL。这将用于我公司内部使用的至少两个不同的软件包,这两个软件包都有一些示例框架代码或此特定接口的空壳。一个供应商在C / C ++中编写了他们的示例,另一个在Fortran中。
理想情况下,我只想用一种语言编写和维护这个库代码,而不是重复它(特别是因为我现在只是在不同风格的C中获得一些舒适度,但是避风港& #39;触及Fortran)。
我已经通过电子邮件发送给我们的供应商,看看他们在导入这个DLL时是否有任何特定的解决方案,但这让我对更基本的层面感到好奇。如果我在C和Fortran中编译一个带有公开方法void foo(int bar)
的DLL ...到它的x86机器指令时 - 它是否会对程序调用该方法的方式产生任何影响#34; X&#34 ;?到目前为止,我已经聚集了,如果我要做 C ++ ,我需要extern "C"
位以避免"重复#34; - 还有什么我应该知道的吗?
答案 0 :(得分:3)
很重要。导出的函数必须使用特定的调用约定,在32位代码中通常使用几个不兼容的函数。调用约定规定了函数参数的存储位置,传递顺序以及如何再次删除它们。以及如何传回函数返回值。
并且函数的名称很重要,导出的函数名称通常是带有额外字符的装饰。这就是extern "C"
的全部内容,它抑制了C ++编译器用来防止重载函数具有相同导出名称的名称错位。因此,名称是C编译器的链接器可以识别的名称。
如果您使用其他语言编写的代码互操作,C编译器进行函数调用的方式几乎就是标准。任何现代Fortran编译器都支持声明,使它们与C程序兼容。当然,这是您正在使用的任何软件供应商已经使用的东西,它提供了一个用Fortran编写的附加组件。反过来说,只要你提供可以被C编译器使用的函数,那么Fortran程序员很有可能能够调用它。
答案 1 :(得分:2)
是的,这里已多次讨论过。研究此标记中的答案和问题https://stackoverflow.com/questions/tagged/fortran-iso-c-binding。
fortran中的extern "C"
相当于bind(C)
。使用内部模块iso_c_binding
完成数据类型的等效性。
还要确保使用相同的调用约定。如果您未手动指定任何内容,则两者的默认值通常相同。在Linux上,这不是问题。
答案 2 :(得分:0)
extern“C”用于C ++代码。因此,如果您的DLL是用C ++编写的,则不得传递任何C ++对象(类)。
如果您坚持使用C类型,则需要确保该函数以单一方式传递参数,例如:使用C的默认值_cdecl
。不确定Fortran使用的是什么。