2

我写了一个 C 库函数,但返回值似乎不正确,即使它在函数中是正确的。

以下是相关代码:

(在 dcml_private.c 中)有问题的函数:

dcml_status _dcml_get_status(struct dcml_device *dev)
{
    uint64_t data;
    dcml_status ret;
    int len;

    libusb_bulk_transfer(dev->handle,
                     DCML_ENDPOINT | LIBUSB_ENDPOINT_IN,
                     (unsigned char *) &data,
                     DCML_REPORT_SZ, &len, RX_TIMEOUT);

    printf("data = %ld\n", data);

    if (len != DCML_REPORT_SZ)
        printf("DCML: LIBUSB ERROR (%s)\n", libusb_error_name(len));
        return STATUS_UNKNOWN;

    ret = data & ~(1>>17);
    return (ret);
}

调用函数:

void _dcml_cmd(dcml_context *ctx, dcml_cmd cmd,
      dcml_status quit_cond, int dur)
{
    struct timeval start;
    struct timeval cur;
    uint32_t stat;

    (void)gettimeofday(&start, NULL);
    (void)gettimeofday(&cur, NULL);
    _dcml_send_cmd(ctx->active, cmd);

    while(difftimeval(cur, start) < dur) {
            sleep(POLL_PERIOD);
            stat = _dcml_get_status(ctx->active);

            printf("status (%d), quit_cond (%d)", stat, quit_cond);
            if (stat == quit_cond)
                  break;

            (void)gettimeofday(&cur, NULL);
    }

    _dcml_send_cmd(ctx->active, CMD_NONE);
}

如您所见,我的函数中有打印语句。在 _dcml_cmd 中,该打印语句的典型输出为

status (65535), quit_cond (2048)

_dcml_get_status 打印在哪里:

data = 128

这意味着返回值在退出 _dcml_get_status 之前立即正确,但在返回调用函数后立即不正确(并且此处的值始终为 65535...)

知道“dmcl_status”是一个枚举可能会有所帮助。将返回类型切换为 uint16_t 并不能解决问题。我认为这可能是溢出问题或其他问题,但更改类型、显式强制转换和添加掩码行并不能解决它。

有什么想法吗?

4

1 回答 1

8

这是因为你有一个坏习惯,就是不要把 { } 放在你的 if 语句之后

   if (len != DCML_REPORT_SZ) {
        printf("DCML: LIBUSB ERROR (%s)\n", libusb_error_name(len));
        return STATUS_UNKNOWN;
   }

也用于fprintf(stderr,...转储错误。向 printf 发送错误是不好的做法:

   if (len != DCML_REPORT_SZ) {
        fprintf(stderr, "DCML: LIBUSB ERROR (%s)\n", libusb_error_name(len));
        return STATUS_UNKNOWN;
   }

调用函数也有同样的问题:

       printf("status (%d), quit_cond (%d)", stat, quit_cond);
        if (stat == quit_cond)
              break;

采用:

       fprintf(stderr, "status (%d), quit_cond (%d)", stat, quit_cond);
        if (stat == quit_cond) {
              break;
        }

是的,它使用了额外的一行,但是在凌晨 3:00 调试它时,通过在不会破坏逻辑的地方添加 fprintfs 来调试它。:^)

于 2013-06-07T04:51:23.057 回答