【发布时间】:2016-06-20 23:39:48
【问题描述】:
这是this question 的后续问题。
我正在尝试从下面看到的 Fortran 90 程序调用一个用 C 编写的客户端。
program name
implicit none
! type declaration statements
character indata, ipaddr, ans, calc
integer portno
indata = "INDATA"
ipaddr = "localhost"
portno = 55555
! executable statements
print *, indata
ans = calc(indata, ipaddr, portno)
print *, ans
end program name
我的 C 程序如下所示
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
/*
int main()
{
calc_("1 2 add", "localhost", 55555);
return 0;
}
*/
void error(char *msg)
{
perror(msg);
exit(0);
}
int calc_(char *indata, char *ipaddr, int *in_portno)
{
int sockfd, portno, n;
struct sockaddr_in serv_addr;
struct hostent *server;
char buffer[256];
portno = in_portno;
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0)
error("ERROR opening socket");
server = gethostbyname(ipaddr);
if (server == NULL) {
fprintf(stderr,"ERROR, no such host\n");
exit(0);
}
memset(((char *) &serv_addr), 0, (sizeof(serv_addr)));
serv_addr.sin_family = AF_INET;
memcpy(((char *)server->h_addr),
((char *)&serv_addr.sin_addr.s_addr),
(server->h_length));
serv_addr.sin_port = htons(portno);
if (connect(sockfd,(struct sockaddr *)&serv_addr,sizeof(serv_addr)) < 0)
error("ERROR connecting");
memset((buffer), 0, (256));
strcpy(buffer, indata);
//fgets(buffer, 255, *indata);
n = write(sockfd, buffer, strlen(buffer));
if (n < 0)
error("ERROR writing to socket");
memset((buffer), 0, (256));
n = read(sockfd,buffer,255);
if (n < 0)
error("ERROR reading from socket");
printf("%s\n",buffer);
return 0;
}
在 C 程序中有一个注释掉的主程序。如果使用 main,一切正常(在 localhost 上运行的服务器回复:3,这是预期的),但是当我尝试运行如上所示的程序时,使用 makefile:
# Use gcc for C and gfortran for Fortran code.
CC=gcc
FC=gfortran
calc : calcf.o fclient.o
$(FC) -o calc calcf.o fclient.o
fclient.o : fclient.c
$(CC) -Wall -c fclient.c
calcf.o: calcf.f90
$(FC) -c calcf.f90
我收到以下错误消息打印到标准输出。
1 //[author's comment], this 1 is from the "1 2 add" printed in the .f90 program
Program received signal SIGSEGV: Segmentation fault - invalid memory reference.
Backtrace for this error:
#0 0x7fd8e9c9430f in ???
#1 0x7fd8e9d6816f in ???
#2 0x7fd8e9d59677 in ???
#3 0x400e0a in ???
#4 0x400cdd in ???
#5 0x400d81 in ???
#6 0x7fd8e9c81740 in ???
#7 0x400b68 in ???
#8 0xffffffffffffffff in ???
zsh: segmentation fault (core dumped) ./calc
我能够理解我正在以某种方式访问受限内存,或者程序不应该修改的内存,但我无法看到这是在哪里发生以及为什么它只是当我从 .f90 程序调用 calc_ 时的情况。
【问题讨论】:
-
首先,将你的 c 程序编译成可执行文件,然后执行:Execute_Command_Line ( Command, Wait, Exitstat, Cmdstat, Cmdmsg ) from FORTRAN
-
我对 Fortran 知之甚少,我现在已经忘记了(关于 Fortran 77),但我尝试了你的程序,当涉及到
calc_时,参数的值非常奇怪。所以我的猜测是这是某种参数传递问题。 -
@ryyker,最终,我希望能够在 fortran 程序中指定 indata,然后让客户端/服务器程序简单地将数据传递给另一个对数据进行一些处理的 Fortran 程序.据了解,这是不可能的,并且 execute_command_line 似乎不是要走的路。
-
您是否使用 CDECL 声明了计算例程?
-
Fortran
CHARACTER和 Cchar *可能彼此不兼容;当我许多年前在VMS系统上做这样的事情时,我不得不在C代码中使用“描述符”类型(基本上,一个包含字符串基地址及其长度的结构) .如果这是一个问题,我不会感到惊讶。