-1

I am creating an SPI extension for my Raspberry Pi, and have encountered a rather strange problem with a class function that I am trying to add. (The repo is here if you want to check anything obvious I am missing: php_spi on Github)

In my php_spi.h I have defined:

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

This is along with a few other methods, similarly defined that currently work. In my spi.c file I have the function defined as follows:

    /* {{{ 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 */

And I have made sure that my function has an entry in the function list:

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 }
};

The code compiles cleanly, with no errors or warnings, but when I try to test the function I get a PHP error saying that the function is not defined. What could I possibly be missing?

(Just to be clear, this is a working extension except for this one function)

EDIT: Thank you for the downvote on a question that is older than one year.

4
  • One idiotic thing I've done in the past is forgetting to define the constant around the ZEND_GET_MODULE() statement. Commented Aug 29, 2012 at 22:02
  • I have that for sure - all of the other parts of my extension work as expected. Commented Aug 30, 2012 at 0:07
  • Maybe it is silly, but what compiler do you use to compile your spi.c? If this is g++ it mayb add type info to your exported functions. Or do you use gcc (if you use unix/linux...) Commented Aug 30, 2012 at 0:19
  • @Grzegorz But why would it only do that for one function - the rest of the methods in my class load just fine Commented Aug 30, 2012 at 9:10

3 Answers 3

0

First thing to check would be if PHP is finding the module - try running php -m on the command line or calling phpinfo() in a web page - is your module listed?

If not, check out How to enable php extension using `phpize`? Also, what's your environment?

Sign up to request clarification or add additional context in comments.

3 Comments

PHP is finding the module as the Spi class instantiates and I can run all of the other methods that I have defined, it is just this one function that doesn't want to work. My environment is Raspbian (based on Debian Wheezy, compiled for ARM), running on a Raspberry Pi
@frak Did you resolve this? I just checked out your Git repo and the blockTransfer method isn't mentioned. But if I copy in the code in the question it works fine...
if you have master checked out you will not see the code, if you try checking out the block-sending branch you should see the code. Odd that it seems to work for you though :S
0

You defined the array Spi_methods, but you don't reference it. It must be referenced in the module structure; see for instance this example.

You don't need to put either the function nor the arginfo prototypes in the main extension header (or any other header, unless you need to reference the symbols in other compilation units, for instance if you defined a function in one file, but build the function entry array in another). In fact, I think it's automatically included in static builds, so you shouldn't in order to avoid name clashes.

1 Comment

I already have this, how else would all of the other methods work without it? The prototype definitions came from PECL_CodeGen so I thought I might as well continue the convention, and it doesn't cause any problems with any of the other methods that I have that work just fine
0

Well, that was a stunning about of time wasted on a typo in my test file :o(

I should have read the error more carefully as it was about the function blockTransfer() being undefined, not the method.

In the test file I had:

$read = $spi-blockTransfer();

Doh!

Sorry for wasting your time.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.