通过引用修改zval时PHP扩展段错误

时间:2015-03-19 17:30:39

标签: php pass-by-reference php-extension

PHP:

$publickey = pack('H*', "03ca473d3c0cccbf600d1c89fa33b7f6b1f2b4c66f1f11986701f4b6cc4f54c360");  
$pubkeylen = strlen($publickey);  
$result = secp256k1_ec_pubkey_decompress($publickey, $pubkeylen);  

C扩展名:

PHP_FUNCTION(secp256k1_ec_pubkey_decompress) {
    secp256k1_start(SECP256K1_START_SIGN);

    zval *pubkey, *pubkeylen;
    unsigned char* newpubkey;
    int newpubkeylen;
    int result;

    if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "zz", &pubkey, &pubkeylen) == FAILURE) {
        return;
    }

    newpubkey = Z_STRVAL_P(pubkey);
    newpubkeylen = Z_LVAL_P(pubkeylen);
    result = secp256k1_ec_pubkey_decompress(newpubkey, &newpubkeylen);

    if (result == 1) {
        newpubkey[newpubkeylen] = 0U;
        ZVAL_STRINGL(pubkey, newpubkey, newpubkeylen, 0);
        ZVAL_LONG(pubkeylen, newpubkeylen);
    }

    RETURN_LONG(result);
}

$ publickey从32字节解压缩到65字节字符串,因为当我们这样做时,我们得到了一个分段错误。
我认为我们正在做一些结构上错误的事情......考虑到这是我们的第一个PHP扩展。

完整代码; https://github.com/afk11/secp256k1-php

1 个答案:

答案 0 :(得分:1)

在查看扩展程序代码后,您在构建扩展程序时尚未链接实际的secp256k1 lib(.so)( #include" secp256k1.h" 不包括实际比特币/ secp256k1代码c库)。

您需要通过以下任何方式更改config.m4

1)将" -l / path /添加到/ bitcoin / secp256k1 / lib"到" gcc"选项。

  

帮助:在这里,我说的是你做了安装"上   比特币/ secp256k1,一些库将安装到/ usr / lib或   / usr / lib64或/ usr / lib / secp256k1等....

-lsecp256k1

// i.e. something like...
PHP_NEW_EXTENSION(secp256k1, secp256k1.c, $ext_shared,, "-lsecp256k1 -DZEND_ENABLE_STATIC_TSRMLS_CACHE=1")

2)或者,从实际的secp256k1库中包含实际的* .c文件

PHP_NEW_EXTENSION(secp256k1, secp256k1.c ../secp256k1/src/secp256k1.c ../secp256k1/src/others.c, $ext_shared,, -DZEND_ENABLE_STATIC_TSRMLS_CACHE=1)

我会推荐选项-1