我正在用 C 编写一个 PHP 扩展,它调用 Fortran 库中的子例程。我可以调用需要 int
或 double
参数的子例程,但我不知道如何传递字符串。这是 Fortran 子例程源代码的片段(我无法更改):
Subroutine abcdef(stringA)
Character *(*) stringA
.................
.................
Return
End Subroutine abcdef
这是我在 C 扩展中的尝试:
extern void abcdef_(char *strA, int *size);
PHP_FUNCTION(abcdef)
{
char *_strA;
int size;
/* Arguments Parsing */
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s",
&_strA, &size) == FAILURE)
{
RETURN_NULL();
}
abcdef_(_strA, &size);
return;
}
也许我在搜索错误的东西,但我发现这方面的信息非常稀少。我是否认为 Character *(*)
只是一个指向字符数组的指针?我已经为参数尝试了许多不同的组合,但似乎无法正确组合。有时当我调用例程时它会出现段错误,其他时候 PHP 没有显示错误但子例程无效。
由于我能够从我的扩展中调用带有 int 和 double 参数的例程,并且这个例程在从 Fortran 调用时工作正常,我认为这一定是我传递字符串的方式,但只是无法找出正确的方法。
最佳答案
这是编译器特定的东西。最好的办法是使用 Fortran 2003 C 互操作性。即使您不能更改(为什么?)原始代码,您始终可以使用 bind(C)
在 Fortran 2003 中编写包装层。
如果您不能这样做,请咨询您的编译器的 ABI。对于 gfortran http://gcc.gnu.org/onlinedocs/gfortran/Argument-passing-conventions.html建议您应该按值传递大小。
这意味着:
str.f90:
subroutine str(s)
character*(*) :: s
print *,s
end subroutine
密码.c:
void str_(char * s, int size);
int main(){
str_("Hello",5);
}
编译运行:
>gfortran str.f90 passstr.c
> ./a.out
Hello
像魅力一样工作。
关于C 中的 PHP 扩展。如何使用字符串参数调用 Fortran 子例程?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20070377/