FORTRAN 函数返回数组导致段错误(从 C++ 调用)

发布于 2024-08-26 15:18:44 字数 591 浏览 7 评论 0原文

基本上,这是我的问题。我从我的 C++ 代码中调用别人的 FORTRAN 函数,这让我很头疼。一些代码:

function c_error_message()
character(len = 255) :: c_error_message
errmsg(1:9) = 'ERROR MSG'
return
end

那是 FORTRAN 函数。我的第一个问题是:里面有什么东西会导致段错误吗?

如果没有,那么第二:返回什么?一个指针? 我尝试使用以下 C 语句来调用它:

char *e = c_error_message_();

这会导致段错误。

c_error_message();

这也会导致段错误。

我之前使用以下代码声明了 c_error_message_():

extern"C" {
    char* c_error_message_();
}

声明具有与实际返回类型不同的返回类型的函数会导致段错误吗?

我不知所措。感谢您的回复。

Basically, here's my problem. I'm calling someone else's FORTRAN functions from my C++ code, and it's giving me headaches. Some code:

function c_error_message()
character(len = 255) :: c_error_message
errmsg(1:9) = 'ERROR MSG'
return
end

That's the FORTRAN function. My first question is: Is there anything in there that would cause a segfault?

If not, then second: What does that return? A pointer?
I'm trying to call it with the following C statement:

char *e = c_error_message_();

That causes a segfault.

c_error_message();

That too causes a segfault.

I declared c_error_message_() earlier on with the following code:

extern"C" {
    char* c_error_message_();
}

Would declaring a function with a different return type than the actual return type cause a segfault?

I'm at a loss. Thanks for any replies.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

浮光之海 2024-09-02 15:18:44

这是一个有效的方法。当我尝试将 ISO C 绑定与返回字符串的函数一起使用时,编译器表示反对。因此,如果您使用子例程参数:

subroutine fort_err_message (c_error_message) bind (C, name="fort_err_message")

use iso_c_binding, only: C_CHAR, C_NULL_CHAR

character (len=1, kind=C_CHAR), dimension (255), intent (out) :: c_error_message

character (len=255, kind=C_CHAR) :: string
integer :: i

string = 'ERROR MSG' // C_NULL_CHAR

do i=1, 255
   c_error_message (i) = string (i:i)
end do

return

end subroutine fort_err_message

Fortran 有点尴尬,因为从技术上讲,C 字符串是一维字符数组。

示例 C 代码演示了该方法的工作原理:

#include <stdio.h>

void fort_err_message ( char chars [255] );

int main ( void ) {

  char chars [255];

  fort_err_message ( chars );

  printf ( "%s\n", chars );

  return 0;

}

Here is a method that works. When I tried to use the ISO C Binding with a function returning a string, the compiler objected. So if instead you use a subroutine argument:

subroutine fort_err_message (c_error_message) bind (C, name="fort_err_message")

use iso_c_binding, only: C_CHAR, C_NULL_CHAR

character (len=1, kind=C_CHAR), dimension (255), intent (out) :: c_error_message

character (len=255, kind=C_CHAR) :: string
integer :: i

string = 'ERROR MSG' // C_NULL_CHAR

do i=1, 255
   c_error_message (i) = string (i:i)
end do

return

end subroutine fort_err_message

The Fortran is a bit awkward because technically a C-string is an 1D array of characters.

And example C code to demo that this works:

#include <stdio.h>

void fort_err_message ( char chars [255] );

int main ( void ) {

  char chars [255];

  fort_err_message ( chars );

  printf ( "%s\n", chars );

  return 0;

}
暖伴 2024-09-02 15:18:44

由于第二行声明的名称与函数名称相同,因此它声明了函数返回的类型,即255个字符的定标字符串。但从理论上讲,这并没有告诉我们内部 API——那是由编译器决定的。我不知道“errmsg”来自哪里——它必须在其他地方声明——也许是迈克尔·安德森建议的全局变量。或者,这可能是一个错误,该行应该是 c_error_message = "ERROR MSG"。 (不需要指定子字符串范围——字符串的其余部分将用空格填充。)IMO,从 C 调用 Fortran 的最佳方法(反之亦然)是使用 ISO C绑定,这将导致 Fortran 编译器使用 C 兼容接口。我还没有完成返回字符串的函数,但已经完成了字符串作为参数。

Since the second line declares a name that is the same as the function name, it is declaring the type of the function return, namely a scaler character string of 255 characters. But in theory this doesn't tell us the internal API -- that is up the the compiler. I don't know where "errmsg" comes from -- it must be declared elsewhere -- perhaps a global variable as suggested by Michael Anderson. Or maybe this is a mistake and the line should be c_error_message = "ERROR MSG". (There is no need to designate the sub-string range -- the rest of the string will be filled with blanks.) IMO, the best approach to calling Fortran from C (or vice-a-versa) is to use the ISO C Binding, which will cause the Fortran compiler to use a C compatible Interface. I haven't done a function returning a string, but have done strings as arguments.

陌路终见情 2024-09-02 15:18:44

FORTRAN 函数返回分配给函数名称的值。返回的类型由函数定义指定,在本例中,它返回一个 255 个字符长的字符串。我认为类型不匹配是你出现段错误的原因。那么您应该使用什么 C 类型呢?我不知道。

我找到了这个 Using C with FORTRAN 页面,作者强烈建议使用 FORTRAN 子例程并将它们作为返回 void 类型的 C 函数调用。

这是F95 快速参考

FORTRAN functions return the value assigned to the function name. The type returned is specified by the function definition, and in this case, it is returning an character string 255 characters long. I think the type mismatch is why you are segfaulting. So what C type should you use? I don't know.

I found this Using C with FORTRAN page, and the author strongly recommends using FORTRAN subtroutines and calling them as C functions returning type void.

Here is an F95 quick reference.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文