使用指针

时间:2017-01-06 17:57:35

标签: c pointers fortran

我正在尝试在C语言中创建一个从Fortran调用的函数。首先要做的事情。 fortran代码用f77编译,c用gcc编译。两者都编译成.so库。 c函数将读取设备上的内存,其大小由fortran指定。我能够看到地址和大小传递给c,但是我在填充c函数中的数据并将其返回到fortran时遇到了问题。请参阅下面的相关代码。我的假设是数据变量的内存分配或指针语法有问题。

C

void copymemory_( uint32_t *addr, int *size, uint8_t *data )
{

    int i;
    printf("addr %x \n", *addr);
    printf("size %i \n", *size);

    for ( i = 0; i<*size; i++)
    {
        *data[i] = i;
        printf("memory %i \n",*data[i]);
    }

}

的Fortran

integer memory(4)
call copymemory(z'dead', 4, memory)

DO i = 1,memsize
   call printf(memory(i))
END DO

1 个答案:

答案 0 :(得分:2)

我对你的代码有几点意见。

请提供可编译代码并描述该确切代码的输出!

这包括标准标题的#include,如果您希望人们调试您的代码,让它们变得容易,以便他们不必搜索您省略了哪些行,因为它们似乎&# 34;明显&#34;给你。只需粘贴一切。从这里复制代码时应编译!

即使代码的可执行部分也不能在我的编译器中编译。我必须将*data更改为data。您确定要复制实际代码吗?

cfun.c: In function ‘copymemory_’:
cfun.c:13:9: error: invalid type argument of unary ‘*’ (have ‘int’)
         *data[i] = i;
         ^
cfun.c:14:31: error: invalid type argument of unary ‘*’ (have ‘int’)
         printf("memory %i \n",*data[i]);
                           ^

您的Fortran代码包含对某个printf子例程的调用。这定义在哪里?它存在于您的实际代码中吗?我对此表示怀疑。请始终将完整且可编译的代码复制到StackOverflow。

所以在修好之后你现在的代码就是:

#include <stdio.h>
#include <stdint.h>

void copymemory_( uint32_t *addr, int *size, uint8_t *data )
{

    int i;
    printf("addr %x \n", *addr);
    printf("size %i \n", *size);

    for ( i = 0; i<*size; i++)
    {
        data[i] = i;
        printf("memory %i \n",data[i]);
    }

}


implicit none

integer :: memsize = 4

integer memory(4)
integer i

call copymemory(z'dead', 4, memory)

DO i = 1,memsize
   print *, (memory(i))
END DO

END

它没有崩溃,但Fortran中的memory包含垃圾。它必须,因为它是integer,你在C中将其视为int8_t

因此要么将其视为C中的四个整数数组,要么逐字节复制,但是必须传递正确的字节数才能复制。从你的描述中不清楚你的意图是哪一个,所以我只展示一种可能性:

void copymemory_( uint32_t *addr, int *size, uint32_t *data )

输出正确:

> gfortran-4.10 -fsanitize=address cfun.c ffun.f90 
> ./a.out 
addr dead 
size 4 
memory 0 
memory 1 
memory 2 
memory 3 
           0
           1
           2
           3