【问题标题】:pointer function returning value issue指针函数返回值问题
【发布时间】:2017-01-24 10:13:58
【问题描述】:

我最近正在开发一个 C 解决方案,我使用函数指针来模拟事件发生时的回调行为。

我很好地围绕着这种 c 语言能力。在我的整个程序中使用它。但我仍然不明白一些行为。

我有一个函数,我返回一个 int,比如说 4。 我在该函数上放置了一个指针,并将其分配给结构中的一个变量。 然后将该结构传递给一个函数,其中我的结构类型的全局变量等于我的回调结构。

到目前为止一切都很好,但是当我使用它自己的回调来检索 4 的 int 值时,它会返回一个错误的值,看起来像一个未初始化的值,或者命中了错误的内存段。

回调在线程中调用,但它不是来自线程池,而是只有一个线程循环检索信息并将其传递给服务器端。所以他们没有对变量的并发访问。

给你一个我的实现的可视化例子:

这里是回调声明

gboolean zeta_transport_is_api_secret_needed(janus_transport *plugin);
gboolean zeta_transport_is_api_secret_valid(janus_transport *plugin, const char *apisecret);
gboolean zeta_transport_is_auth_token_needed(janus_transport *plugin);
gboolean zeta_transport_is_auth_token_valid(janus_transport *plugin, const char *token);
int      zeta_transport_get_server_load();

static zeta_transport_callbacks zeta_handler_transport =
        {
                .incoming_request = zeta_transport_incoming_request,
                .transport_gone = zeta_transport_gone,
                .is_api_secret_needed = zeta_transport_is_api_secret_needed,
                .is_api_secret_valid = zeta_transport_is_api_secret_valid,
                .is_auth_token_needed = zeta_transport_is_auth_token_needed,
                .is_auth_token_valid = zeta_transport_is_auth_token_valid,
                .get_server_load = zeta_transport_get_server_load,
        };

我声明函数指针的头文件 transport.h:

struct janus_transport_callbacks {
...
        int (* const get_server_load)();
}

这是我调用传输层的 init 函数:

janus_transport->init(&zeta_handler_transport, configs_folder);

传输层初始化函数:

int janus_websockets_init(zeta_transport_callbacks *callback, const char *config_path) {
    if(g_atomic_int_get(&stopping)) {
        /* Still stopping from before */
        return -1;
    }
    if(callback == NULL || config_path == NULL) {
        /* Invalid arguments */
        return -1;
    }

    /* This is the callback we'll need to invoke to contact the gateway */
    gateway = callback;
    /* I then call the thread where the callback will be called to retrieve the integer of 4 */
    g_thread_try_new("Client_start", Client_start, NULL, NULL);

一旦线程在这里启动,我就是如何调用“回调”

int ret = gateway->get_server_load;
      printf(KRED"Server load = %d .\n"RESET, ret);

最后是输出:

Server load = 4416800 .

我仍在获取,但我真的几天都看不到我的错误。

【问题讨论】:

  • int ret = gateway->get_server_load; 不调用该函数 - 它只是一个地址。 int ret = gateway->get_server_load();呢?
  • 您是否启用了所有编译器警告?为什么不呢?
  • 我会马上尝试,不是所有的警告我都会把 -W 放在我的 makefile 中。谢谢
  • 这不是“所有警告”。你需要的是-W -Wall -Wextra -pedantic-errors,可能是-std=c11(或c99c89,具体取决于要求)。
  • 它正在工作(感谢您的帮助)!!!根据你给我的警告,我有旧式函数定义 [-Wold-style-definition] int janus_transport_get_server_load() 所以基本上我是在询问函数的地址,这就是我要打印的内容?

标签: c callback function-pointers


【解决方案1】:

你忘了call你的回调。改变

int ret = gateway->get_server_load;

int ret = gateway->get_server_load();
//                               ^^^^

【讨论】:

  • 这必须产生编译器错误/警告。将函数指针分配给整数不是“简单分配”的有效形式。
  • 第一个实现还是第二个实现?
猜你喜欢
  • 2014-08-03
  • 1970-01-01
  • 2011-12-02
  • 2017-09-05
  • 2018-03-07
  • 1970-01-01
  • 2013-04-10
  • 1970-01-01
  • 2018-05-30
相关资源
最近更新 更多