带有 void * 指针的 Typedef 函数

Typedef function with void * pointer

我正在尝试实现库中定义的函数,但在使用时遇到问题。 This问题帮我实现了,但是我无法使用这个功能。

这是类型定义:

typedef void (*paillier_get_rand_t) ( void* buf, int len );

下面是我的实现方式:

void get_rand(void* buf, int len) {
  buf = (void *)rand();  // I don't know if it works but isn't the problem
}

下面是我如何创建指向函数的指针并调用它。

   int modulus = 4;
    void* buf;
    paillier_pubkey_t* pub;
    paillier_prvkey_t* prv;
    paillier_keygen(modulus, &pub, &prv, &get_rand);                

问题1)如何发送参数buf和len? 问题2)现在错误不同了:

reference to `paillier_keygen(int, paillier_pubkey_t**, paillier_prvkey_t**, void (*)(void*, int))' undefined

函数paillier_keygen用于生成算法的相应密钥,函数get_rand用于获得概率算法所需的随机性。

我正在实现这个 typedef,因为我需要这样做才能使用库。

编辑:

我找到了一个已定义的函数,我可以使用它 paillier_get_rand_devurandom

/* 这些函数可以传递给 paillier_keygen 和 paillier_enc 提供随机数来源的函数。这 首先从 /dev/random 读取字节。 Linux,此设备 完全 returns 从环境噪音中收集的熵和 因此在可用资源不足时经常阻塞。第二 来自 /dev/urandom 的 returns 个字节。在 Linux 上,此设备还 returns 环境噪声,但用伪随机数增强它 发电机不足时可用。后者大概是 更好的选择,除非你有特定的理由相信它是 不足的。 */

void paillier_get_rand_devurandom( void* buf, int len );

如果我像以前一样使用

paillier_keygen(modulus, &pub, &prv, paillier_get_rand_devurandom(buf, 4));

我得到error: invalid use of void expression

如果我这样使用:

paillier_keygen(modulus, &pub, &prv, &paillier_get_rand_devurandom);

我得到:

undefined reference to `paillier_get_rand_devurandom(void*, int)'
undefined reference to `paillier_keygen(int, paillier_pubkey_t**, paillier_prvkey_t**, void (*)(void*, int))'

库已包含在内。在这里我添加更多关于签名的信息:

/* 使用来自的随机性生成长度模数位的密钥对 提供get_rand功能。 Space 将分配给每个 键,并且给定的指针将被设置为指向新的 paillier_pubkey_t 和 paillier_prvkey_t 结构。功能 paillier_get_rand_devrandom 和 paillier_get_rand_devurandom 可能是 作为最后的论点通过。 */

void paillier_keygen( int modulusbits,
            paillier_pubkey_t** pub, paillier_prvkey_t** prv, paillier_get_rand_t get_rand );

/* 这是用于获取的回调函数的类型 概率算法所需的随机性。功能 paillier_get_rand_devrandom 和 paillier_get_rand_devurandom (稍后记录)可以传递给任何需要 paillier_get_rand_t,或者您可以实现自己的。如果你实施 你自己的这样的功能,它应该填写 "len" 随机字节 数组 "buf"。 */

typedef void (*paillier_get_rand_t) ( void* buf, int len );

我在这里有点猜测,因为您没有显示所有函数的原型(及其文档),但您几乎肯定想要这个:

paillier_pubkey_t* pub;
paillier_prvkey_t* prv;
paillier_keygen(modulus, &pub, &prv, &get_rand);

get_rand可能会做类似的事情:

void get_rand(void* buf, int len)
{
    char* bytes = (char*)buf;
    for (int i = 0; i != len; ++i) {
        bytes[i] = rand() & 0xff;
    }
}

当您声明以下内容时,您正在取消引用并调用 get_rand_function 的值:

(*get_rand_funtion)(&buf, 4)

由于声明的 return 类型为 void,编译器将表达式的结果解释为 void,这不是函数参数的有效类型。如果您希望将指针传递给函数 paillier_keygen 那么@Cameron 代码是正确的。至少在 C99 和更早版本中,您不能将值绑定到函数指针。

我找到了解决方案。首先,我像 extern 一样导入库,因为 paillier.h 是用 C 编写的,而我使用的是 C++。

就像这样:

use #include <gmp.h>
extern "C"{
    #include "paillier.h"
}

之后我还使用 -lpaillier-lgmp 进行了编译。

最终代码为:

paillier_pubkey_t* pub;
    paillier_prvkey_t* prv;
    paillier_keygen(1024, &pub, &prv, paillier_get_rand_devurandom);

无需定义任何附加函数。