c - 如何在 Fortran 中调用 C 函数并正确传递 uint32_t 参数

标签 c fortran fortran-iso-c-binding uint32

您好,我正在使用 Fortran 90 代码调用 C 函数。由于我正在处理地址,C 函数的参数应该在 Fortran 中正确匹配。我正在使用 ifort 和 icc 编译代码并在 64 位机器上工作。

一些测试表明这也适用于 int32_t,尽管为了防止最终的陷阱,我想保留 uint32_t

我调用的 C 函数具有以下原型(prototype)

uint32_t encode_(uint32_t x, uint32_t y)
uint32_t decode_(uint32_t dec)

我不能简单地通过做类似的事情来调用这些函数

integer :: cod,encode
cod = encode(i,j)

这会产生乱码。因此,我正在使用一种解决方法:

void code2d_(uint32_t j[] ){


uint32_t i;

i=encode_(j[0],j[1]);  
// the underscore is due to the FORTRAN naming convention

printf("Coded %10d  \n",i);

}

然后在 Fortran 中

 integer :: cod,code2d
 cod = code2d(i,j)

很明显,我对参数类型不匹配有一些疑问。不幸的是我不知道如何解决这个问题。由于在我的解码/编码函数中完成了二进制地址算法,因此保留 uint32_t 非常重要。

最佳答案

当您使用标签时,您似乎了解 iso_c_binding。研究 Fortran 2003 与 C 的互操作性。阅读标签描述和一些文档,例如 http://gcc.gnu.org/onlinedocs/gcc-4.9.0/gfortran/Interoperability-with-C.html .在现代 Fortran 中,尾随的下划线和类似的东西是没有位置的。

Fortran 没有任何无符号类型,您必须使用有符号类型。只要带符号的值为正,它就可以工作。如果您需要更大的值,请使用更大的整数类型。如果需要,您可以将低位字节transfer() 为 int32。

第三,Fortran 默认使用引用传递的一些变体,特别是对于 bind(c) 过程(它可能是对副本或其他变体的引用)。您必须使用 value 属性按值传递。

uint32_t encode(uint32_t x, uint32_t y)
uint32_t decode(uint32_t dec)

module c_procs
  interface
    function encode(x, y) bind(C, name="encode")
      use iso_c_binding
      integer(c_int32_t) :: encode
      integer(c_int32_t), value :: x, y
    end function
    function decode(x, y) bind(C, name="decode")
      use iso_c_binding
      integer(c_int32_t) :: decode
      integer(c_int32_t), value :: dec
    end function
  end interface
end module

...

use iso_c_binding
use c_procs

integer(c_int32_t) :: cod, i, j
cod = encode(i,j)

最新版本的 GCC 能够检测到我们在链接时优化期间混合了有符号和无符号类型:

rng.f90:173:0: warning: type of 'sub' does not match original declaration [-Wlto-type-mismatch]
     ival = sub(jz, jsr)
^
rng_c.c:2:10: note: return value type mismatch
 uint32_t sub(uint32_t a, uint32_t b) {
          ^
/usr/include/stdint.h:51:23: note: type 'uint32_t' should match type 'int'
 typedef unsigned int  uint32_t;
                       ^
rng_c.c:2:10: note: 'sub' was previously declared here
 uint32_t sub(uint32_t a, uint32_t b) {

如果您知道自己在做什么,可以忽略警告或将其禁用。

关于c - 如何在 Fortran 中调用 C 函数并正确传递 uint32_t 参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24726446/

相关文章:

gcc - Fortran 77 提示常见 block

c++ - 为什么这种将指针从 C++ 传递到 Fortran 的尝试不起作用?

c - 将可变长度字符串分配给固定长度字符串

c - 接收多条消息的socket编程C

c - 如何在 win32 上为 mingw 使用 makefile

c++ - 将大量数据从 FORTRAN 传递到 C++

debugging - 在 Fortran 中查找 write 语句

c++ - 从 C++ 调用带有可选参数的 Fortran 子例程

我们可以用C语言读取smoking.mat(数据集)吗?

c - 优化简单的模具操作,将变量保存在寄存器中