【问题标题】:Typedef function with void * pointer带有 void * 指针的 Typedef 函数
【发布时间】:2015-02-03 20:29:09
【问题描述】:

我正在尝试实现一个库中定义的函数,但我在使用它时遇到了问题。 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,因为我需要这样做才能使用 lib。

编辑:

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

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

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 函数。空间将被分配给每个 键,并且给定的指针将被设置为指向新的 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_get_rand_t fnPtr = &getRand; 并将 fnPtr 作为参数传递。
  • 我猜paillier_pubkey_t** pub; 是错误的,你应该使用paillier_pubkey_t* pub; 并使用&pub 传递给函数。 (即它可能需要一个指向它可以访问的内存的指针,你正在提供一些会崩溃的访问)。
  • buf = (void *)rand(); // I don't know if it works but isn't the problem 毫无意义。
  • 你定义了一个类型paillier_get_rand_t,但是你永远不会在任何地方使用它。这向我表明您要么遗漏了重要代码,要么在某处有错字,要么您完全不知道自己在做什么(在这种情况下,您可能应该停下来。您要做什么?如果您'试图做的是理解 C++ 的每一个角落和缝隙,而你没有更大的目的,停下来。那是浪费时间。C++ 充满了重叠的功能。你可能已经知道一些同样有效的方法来完成同样的事情这个构造可能会做的事情。)
  • @ArtOfWarfare 这是我第一次使用这种函数和指针。我需要实现它以与库一起工作,这可以帮助我在我正在实现的协议中进行加密。

标签: c++ c pointers


【解决方案1】:

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

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

【讨论】:

  • 但是如果这就是他想要的,那么他为什么要键入def paillier_get_rand_t
  • 我感觉paillier库声明了typedef,他正在尝试实现相应的功能。我根据惯用的 C 接口的外观做了一些猜测。
  • @Cameron 是对的,我正在尝试实现库paillier 的相应功能。我更新了代码,提供了更多信息以及修改后出现的错误。
  • @Niemand:你的问题更清楚了,谢谢。但是,我仍然没有足够的信息来确定什么不起作用——paillier_keygen 函数的声明签名是什么? (这是您尝试使用的,因此我们需要知道它的外观以帮助您正确使用它。)您是否链接到适当的库? (你得到的错误信息看起来很像一个链接器错误,如果函数被正确声明和使用,但它的编译代码却找不到。)
  • @Niemand:对,这很有帮助,谢谢。看来我的猜测是正确的——我的示例调用和你的第二个&paillier_get_rand_devurandom 都是正确的。从错误来看,您似乎包含了正确的标头并且代码可以正确编译,但是在链接时它会失败,因为没有链接到 paillier 库。您需要链接到 libpaillier。如何做到这一点完全取决于您的编译器、操作系统以及库是静态的还是动态的。
【解决方案2】:

我找到了解决方案。首先我像 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);

不需要定义任何额外的功能。

【讨论】:

  • 遇到同样的问题,很高兴看到解决方案。
  • @1a1a11a 你能告诉我如何用 -lpaillier 和 -lgmp 编译吗?为了生成makefile,我确实喜欢“./configure LIBS=-lgmp”和“./configure LIBS=-lpaillier”,但是发生了错误。
  • @user2642459 你在编译什么?
  • @1a1a11a 我正在编译 gmp 和 paillier 两个库。
  • 编译gmp的时候不需要什么特别的
【解决方案3】:

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

(*get_rand_funtion)(&buf, 4)

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-05-21
    • 2017-04-18
    • 1970-01-01
    • 2018-08-25
    • 1970-01-01
    • 2011-05-16
    • 1970-01-01
    • 2021-05-09
    相关资源
    最近更新 更多