- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
这是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
#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;
}
# 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
calc_
时才会出现这种情况。
最佳答案
在Fortran 2003引入C互操作功能之前,从Fortran调用外部C函数需要特定于目标环境和所涉及的编译器的技巧此外,如果所讨论的C函数不是专门设计为可由所涉及的Fortran编译器生成的代码调用的,那么通常需要编写一个包装函数(用C语言)来弥合这一差距。
要克服的主要问题是
名称管理:Fortran源代码中引用函数的名称通常与链接器必须链接的名称不同通常会引入一个或多个附加下划线,并且通常会将函数名放入标准大小写中(通常为小写,但有些编译器使用大写)。
参数类型:有些Fortran参数类型根本无法干净地传递,至少在没有相关Fortran实现的详细知识的情况下是这样假定的形状数组、数组节和具有allocatable
或pointer
属性的数组通常是有问题的。
类型表示:这里最大的一个是数组索引顺序Fortran数组按列主顺序编制索引,而C数组按行主顺序编制索引这不一定是传递数组的问题(但也请参见上面的内容);相反,在调用的一边和另一边正确使用数组是一个问题这里的另一个重要特点是Fortrancharacter
对象(字符串)不以空结尾相反,每个值都有一个固定长度,包含在值表示中。这通常通过传递两个实际参数(一个指向char
数组开头的指针和一个长度)在C函数接口上进行调整,但也使用了其他形式。
函数调用语义:Fortran通过引用传递所有参数。它通常显示为一个C函数接口,其中的参数都是指针,除了上面描述的字符串长度参数(因为Fortrancharacter
对象有固定的宽度)。
参数顺序:Fortran可调用的C函数通常使用与Fortran端调用预期使用的参数顺序相同的参数顺序,但这是不保证的,而且无论如何,字符串长度的参数都不能完全适应这种情况。一些Fortran编译器在相应指针之后立即传递它们;另一些则在参数列表的末尾将所有字符串长度参数分组(当然,这并不考虑那些使用完全不同的机制来表示字符串参数的情况。)
可以想象,我忽略了一些事情。
几乎所有这一切都有实质性的实现依赖性,但是人们从Fortran 90诞生之前就一直在Fortran和C之间来回调用,而且他们还在继续这样做如果您没有可以依赖的标准化C互操作的好处,那么您需要了解Fortran编译器如何生成代码的一些细节有各种各样的自动化工具可以实现这一点,包括在GNU Autoconf中,或者您可以查阅文档,甚至进行实验。
值得一提的是,您似乎有几个问题,有些在上面描述的领域,有些完全在Fortran部分在Fortran部分中特别值得注意的是,您没有为character
变量声明长度,因此它们都得到默认长度(1)这显然不是你想要的在函数调用时,Fortran不使用以空结尾的字符串,并为字符串长度传递额外的参数,这也会使您出错。
但是Fortran 2003已经有13年的历史了,C互操作位被广泛实现,包括在gfortran
中,Makefile显示这是Fortran的实现gfortran
文档覆盖了C interop相当彻底对于这个已经冗长的答案来说,有太多了,但关键点包括:
用自然C写出C部分。
使用ISO_C_BINDING
模块。
向C函数编写Fortraninterface
,适当地定义形式参数和返回类型,包括适当的属性(从kind
提供的参数值中提取)
将ISO_C_BINDING
属性应用于必须与C互操作的符号
关于c - 从Fortran 90调用用C编写的客户端程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37923144/
我只想从客户端向服务器发送数组 adc_array=[w, x, y, z]。下面是客户端代码,而我的服务器是在只接受 json 的 python 中。编译代码时我没有收到任何错误,但收到 2 条警告
我是 lua 和 Node js 的新手,我正在尝试将我正在开发的移动应用程序连接到服务器。问题是它连接到服务器,但我尝试传递的数据丢失或无法到达服务器。对我正在做的事情有什么问题有什么想法吗? th
我在这个页面上工作 http://www.haskell.org/haskellwiki/99_questions/Solutions/4 我理解每个函数的含义,看到一个函数可以像这样以多种方式定义,
我目前正在尝试将数据写入 excel 以生成报告。我可以将数据写入 csv 文件,但它不会按照我想要的顺序出现在 excel 中。我需要数据在每列的最佳和最差适应性下打印,而不是全部打印在平均值下。这
所以,我正在做一个项目,现在我有一个问题,所以我想得到你的帮助:) 首先,我已经知道如何编写和读取 .txt 文件,但我想要的不仅仅是 x.hasNext()。 我想知道如何像 .ini 那样编写、读
我正在尝试编写一个函数,该函数将返回作为输入给出的任何数字的阶乘。现在,我的代码绝对是一团糟。请帮忙。 function factorialize(num) { for (var i=num, i
这个问题已经有答案了: Check variable equality against a list of values (16 个回答) 已关闭 4 年前。 有没有一种简洁或更好的方法来编写这个条件
我对 VR 完全陌生,正在 AFrame 中为一个类(class)项目开发 VR 太空射击游戏,并且想知道 AFrame 中是否有 TDD 的任何文档/标准。有人能指出我正确的方向吗? 最佳答案 几乎
我正在尝试创建一个 for 循环,它将重现以下功能代码块,但以一种更具吸引力的方式。这是与 Soundcould 小部件 API 实现一起使用的 here on stackoverflow $(doc
我有一个非常令人困惑的问题。我正在尝试更改属性文件中的属性,但它只是没有更改... 这是代码: package config; import java.io.FileNotFoundException
我对 VR 完全陌生,正在 AFrame 中为一个类(class)项目开发 VR 太空射击游戏,并且想知道 AFrame 中是否有 TDD 的任何文档/标准。有人能指出我正确的方向吗? 最佳答案 几乎
我正在开发一个用户模式(Ring3)代码级调试器。它还应支持.NET可执行文件的本机(x86)调试。基本上,我需要执行以下操作: 1).NET在隐身模式下加载某些模块,而没有LOAD_DLL_DEBU
我有一个列表,我知道有些项目是不必要打印的,我正在尝试通过 if 语句来做到这一点...但是它变得非常复杂,所以有没有什么方法可以在 if 语句中包含多个索引而无需打印重写整个声明。 看起来像这样的东
我很好奇以不同方式编写 if 语句是否会影响程序的速度和效率。所以,例如写一个这样的: bool isActive = true; bool isResponding = false; if (isA
我在搜索网站的源代码时找到了一种以另一种方式(我认为)编写 if 语句的方法。 代替: if(a)b; 或: a?b:''; 我读了: !a||b; 第三种方式和前两种方式一样吗?如果是,为什么我们要
我的数据采用以下格式(HashMap的列表) {TeamName=India, Name=Sachin, Score=170} {TeamName=India, Name=Sehwag, Score=
我目前正在完成 More JOIN operations sqlzoo 的教程,遇到了下面的代码作为#12 的答案: SELECT yr,COUNT(title) FROM movie JOIN ca
我正试图找到一种更好的方法来编写这段代码: def down_up(array, player) 7.downto(3).each do |row| 8.times do |col
出于某种原因,我的缓冲区中充满了乱码,我不确定为什么。我什至用十六进制编辑器检查了我的文件,以验证我的字符是否以 2 字节的 unicode 格式保存。我不确定出了什么问题。 [打开文件] fseek
阅读编码恐怖片时,我刚刚又遇到了 FizzBuzz。 原帖在这里:Coding Horror: Why Can't Programmers.. Program? 对于那些不知道的人:FizzBu
我是一名优秀的程序员,十分优秀!