c - 无法在我的 C 代码中初始化回调。不兼容的引用类型导致未定义的行为

标签 c oop pointers callback undefined-behavior

问题陈述:我正在我的代码中初始化回调 ops->cmd = pando_entry_cb 但由于 < strong>不兼容的指针类型。我知道它说的是什么问题,但不知道我的代码中有什么错误。


下面提供的代码给出了 UB。我想知道如何更正它。

UB代码:

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <unistd.h>

typedef struct proc proc_t;
typedef struct proc_ops proc_ops_t;

proc_t *proc_new(proc_ops_t *ops);

struct proc_ops {
    //this is the callback
    int (*cmd)(proc_ops_t *ops, const void *tx_buf, unsigned tx_count, void *rx_buf, unsigned *rx_count);
    void *priv;
};

struct proc {
    proc_ops_t *ops;
};
//EDIT: Changed the return type
static int pando_entry_cb(proc_t *proc,  const void *tx_buf, unsigned tx_count,
               void *rx_buf, unsigned *rx_count) {

    printf("CB Entry point is called\n");
    printf("FROM_CB: D_proc: tx: %p, t_count: %d, rx :%p, r_count: %p\n", tx_buf,
      tx_count, rx_buf, rx_count);
    //EDIT
    return 1;
}

int proc_cmd(proc_t *proc, const void *tx_buf, unsigned tx_count,
               void *rx_buf, unsigned *rx_count) {
    int r;
    char s[256];

    printf("D_proc: tx: %p, t_count: %d, rx :%p, r_count: %p\n", tx_buf,
            tx_count, rx_buf, rx_count);
    r = proc->ops->cmd(proc->ops, tx_buf, tx_count, rx_buf, rx_count);
    if (r < 0) {
        return -1;
    }
    //EDIT : Added the return type
    return 0;
}

proc_t *proc_new(proc_ops_t *ops) {
    proc_t *proc = malloc(sizeof(*proc));

    printf("Hello allocating the memory to proc struct\n");

    if (!proc) {
        printf("LOG_ERR :%s: malloc failed", __func__);
        return NULL;
    }

    memset(proc, 0, sizeof(*proc));

    //intitalize the struct callback and opaque pointer
    // problem is here where callback assignment from incompitable pointer type
    // Getting UB, here I know the pointer assignment isn't matching.
    // problem what I'm facing is this :  If a converted pointer is used to call a function
    // whose type is not compatible with the referenced type, the behavior is undefined.
    ops->cmd = pando_entry_cb;  // <-- UB
    ops->priv = proc;

    return proc;
}

int main() {
  proc_t *proc;

  proc_ops_t *ops;
  // EDIT: Allocated the memory to ops
  proc_ops_t *ops = malloc(sizeof(*ops));
  memset(ops, 0, sizeof(*ops));
  proc = proc_new(ops);
  if (!proc) {
      return -1;
  }
  //Here I typecasted to void * to match the signature of function.
  proc_cmd(proc, (void*)8, 4, 0, 0);

  return 0;
}

希望我的预期输出如下所示:

Hello allocating the memory to proc struct
D_proc: tx: 0x8, t_count: 4, rx :(nil), r_count: (nil)
CB Entry point is called
FROM_CB: D_proc: tx: 0x8, t_count: 4, rx :(nil), r_count: (nil)

如果有人指出我做错了什么,那会很棒吗?

编辑:

  • 我将函数指针的返回类型和我初始化的函数更改为与 int 相同的类型。
  • 将内存分配给我错过的对象。
  • 将返回类型添加到我的函数 int proc_cmd()

不过,我得到了 UB。

感谢您的帮助。

最佳答案

cmd 的数据类型与您要分配给它的函数进行比较

int (*cmd)(proc_ops_t *ops, const void *tx_buf, unsigned tx_count, void *rx_buf, unsigned *rx_count);
static void pando_entry_cb(proc_t *proc,  const void *tx_buf, unsigned tx_count, void *rx_buf, unsigned *rx_count)

返回类型与第一个参数的类型不同。你的代码期望函数返回一些东西,所以你绝对应该让它返回一个 int,即使它总是 0

然后在 proc_cmd 中,如果 r 为负,它只会返回一些内容。同样,您应该让它返回 0r 的实际值(如果适用)。

您还向 proc_new 传递了一个未分配的值,因为在我看到的代码中,ops 没有在任何位置分配。

最后,当您创建 proc_t 时,您不会填充它的 ops 副本,因此当您稍后使用它时,它不会被设置。您想在返回之前将此行添加到 proc_new 的末尾。

proc->ops=ops;

关于c - 无法在我的 C 代码中初始化回调。不兼容的引用类型导致未定义的行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44069981/

相关文章:

c - 将值放入c中的数组中

matlab - 如何找到自己的类创建的对象?

java - 代码重构: Outsourcing substeps to helper classes

php - OOP PHP 集成 mysqli_query

c - 从类型 `' 分配给类型 ]'` 时不兼容的类型

c - 没有类型的外部

c++ - 更改函数指向的内容

c - C 中带指针和结构的链表

c - 获取条件表达式的地址

c - systeminfo 如何打印行?