【问题标题】:PHP extension in C. How do I call a Fortran subroutine with a character string argument?C 中的 PHP 扩展。如何使用字符串参数调用 Fortran 子例程?
【发布时间】:2013-11-19 11:31:47
【问题描述】:

我正在用 C 编写一个 PHP 扩展,它调用 Fortran 库中的子例程。我可以调用需要intdouble 参数的子例程,但我不知道如何传递字符串。这是 Fortran 子程序源的 sn-p(我无法更改):

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 调用该例程时工作正常,我认为这一定是我传递字符串的方式,但只是找不到正确的方法。

【问题讨论】:

    标签: php c fortran


    【解决方案1】:

    这是编译器特定的东西。最好的办法是使用 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
    

    passstr.c:

    void str_(char * s, int size);
    int main(){
     str_("Hello",5);
    }
    

    编译运行:

    >gfortran str.f90 passstr.c
    > ./a.out 
     Hello
    

    像魅力一样工作。

    【讨论】:

    • 感谢您的回答,我已经尝试过了。问题一定是别的,但至少我现在知道这是正确的,所以我可以查明实​​际问题。
    • 但是在您问题的代码中您使用的是&size,我希望您知道这一点。
    猜你喜欢
    • 1970-01-01
    • 2017-02-11
    • 1970-01-01
    • 2014-01-14
    • 2012-01-02
    • 2017-06-11
    • 2017-02-26
    相关资源
    最近更新 更多