-1

我正在为我的 Raspberry Pi 创建一个 SPI 扩展,并且在尝试添加的类函数中遇到了一个相当奇怪的问题。(如果你想检查我遗漏的任何明显的东西,repo 就在这里:Github 上的 php_spi

在我的 php_spi.h 中,我定义了:

PHP_METHOD(Spi, blockTransfer);
#if (PHP_MAJOR_VERSION >= 5)
ZEND_BEGIN_ARG_INFO_EX(Spi__blockTransfer_args, ZEND_SEND_BY_VAL, ZEND_RETURN_VALUE, 1)
#if (PHP_MINOR_VERSION > 0)
  ZEND_ARG_ARRAY_INFO(0, data, 1)
#else
  ZEND_ARG_INFO(0, data)
#endif
  ZEND_ARG_INFO(0, colDelay)
  ZEND_ARG_INFO(0, discard)
ZEND_END_ARG_INFO()
#else /* PHP 4.x */
#define Spi__blockTransfer_args NULL
#endif

这与其他一些方法一起,类似地定义了当前有效。在我的 spi.c 文件中,函数定义如下:

    /* {{{ proto array blockTransfer(array data[, int colDelay[, bool discard]])
   */
PHP_METHOD(Spi, blockTransfer)
{
    zend_class_entry * _this_ce;

    zval * _this_zval = NULL;
    zval * data = NULL;
    HashTable * data_hash = NULL;
    long colDelay = 1;
    zend_bool discard = 0;

    if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "a|lb", &_this_zval, Spi_ce_ptr, &data, &colDelay, &discard) == FAILURE) {
        return;
    }

    _this_ce = Z_OBJCE_P(_this_zval);

    // some code
}
/* }}} blockTransfer */

我已经确保我的函数在函数列表中有一个条目:

static zend_function_entry Spi_methods[] = {
    PHP_ME(Spi, __construct, Spi____construct_args, /**/ZEND_ACC_PUBLIC | ZEND_ACC_CTOR)
    PHP_ME(Spi, __destruct, Spi____destruct_args, /**/ZEND_ACC_PUBLIC | ZEND_ACC_DTOR)
    PHP_ME(Spi, transfer, Spi__transfer_args, /**/ZEND_ACC_PUBLIC)
    PHP_ME(Spi, blockTransfer, Spi__blockTransfer_args, /**/ZEND_ACC_PUBLIC)
    PHP_ME(Spi, getInfo, Spi__getInfo_args, /**/ZEND_ACC_PUBLIC)
    PHP_ME(Spi, setupTimer, Spi__setupTimer_args, /**/ZEND_ACC_PUBLIC)
    PHP_ME(Spi, usecDelay, Spi__usecDelay_args, /**/ZEND_ACC_PUBLIC)
    { NULL, NULL, NULL }
};

代码编译干净,没有错误或警告,但是当我尝试测试该函数时,我收到一个 PHP 错误,指出该函数未定义。我可能会错过什么?

(为了清楚起见,这是一个工作扩展,除了这个功能)

编辑:感谢您对超过一年的问题投反对票。

4

3 回答 3

0

首先要检查的是 PHP 是否正在查找模块 - 尝试php -m在命令行上运行或phpinfo()在网页中调用 - 是否列出了您的模块?

如果没有,请查看如何使用 `phpize` 启用 php 扩展? 还有,你的环境是什么?

于 2012-08-30T01:32:15.817 回答
0

您定义了数组Spi_methods,但没有引用它。必须在模块结构中引用;例如看这个例子

您不需要将函数或 arginfo 原型放在主扩展标头(或任何其他标头,除非您需要在其他编译单元中引用符号,例如,如果您在一个文件中定义了一个函数,但构建另一个中的函数入口数组)。事实上,我认为它会自动包含在静态构建中,所以你不应该为了避免名称冲突。

于 2012-08-30T20:08:34.743 回答
0

好吧,那是在我的测试文件中的一个错字上浪费了惊人的时间:o(

我应该更仔细地阅读错误,因为它是关于函数 blockTransfer() 未定义,而不是方法。

在我的测试文件中:

$read = $spi-blockTransfer();

嗬!

很抱歉浪费您的时间。

于 2012-09-03T22:09:56.353 回答