【问题标题】:Calling a compiled C library function from Qt C++ produces unexpected behaviour从 Qt C++ 调用已编译的 C 库函数会产生意外行为
【发布时间】:2020-04-15 21:03:33
【问题描述】:

我在 Windows 上,我有 2 个项目:一个是用 C 制作的,我已经编译成一个 DLL 库,另一个是 Qt C++ 项目,我正在与 C 库链接。

当我过去尝试将 C 库与 C 代码链接时,它工作正常。但是,当我尝试将它与 C++ 代码链接时(在此处的 Qt 和一般的 Linux 上)似乎存在问题,即使我在包含 C 头文件的位置插入 extern "C" 块。

最奇怪的部分是在调试时,代码做了一些……不应该发生的事情?

这是我调用的 C 代码:

// Defined in a header file elsewhere...
typedef struct _nodeTrueProperties {
    bool isDefined;
    bool needFuncName;
    bool _mallocd;

    const DType *inputTypes;
    long numInputs;

    const DType *outputTypes;
    long numOutputs;
} NodeTrueProperties;

// The actual code...
NodeTrueProperties d_semantic_get_node_properties(struct _sheet *sheet,
                                                  const char *name,
                                                  size_t lineNum,
                                                  const char *funcName,
                                                  NameDefinition *definition) {
    VERBOSE(5, "Getting node properties of node %s on line %zu in %s...\n",
            name, lineNum, sheet->filePath)

    NodeTrueProperties out =
        (NodeTrueProperties){false, false, true, NULL, 0, NULL, 0};

    // Most cases use this to build up the output types.
    DType *outputTypes = NULL;

    // First, let's check if it's a special function like Start.
    // We do this now so we don't need to search all of our includes
    // for this function.
    if (strcmp(name, "Start") == 0) {

        // THIS IS THE SECTION THAT SHOULD AND DOES RUN!

        out.isDefined  = true;
        out.numOutputs = 1;

        outputTypes    = (DType *)d_malloc(sizeof(DType));
        outputTypes[0] = TYPE_EXECUTION;

        out.outputTypes = (const DType *)outputTypes;
    } else if (strcmp(name, "Return") == 0) {
        // ... stuff that shouldn't run...
    } // ...

    return out;
}

这是调用该函数的 Qt C++ 代码:

#include "nodegraphicsitem.h"

#include <QPainter>

extern "C" {
    #include <dsemantic.h>
}

// ...

void NodeGraphicsItem::setupNode(Sheet *sheet, QString name, QPointF position) {
    _name = name;
    _position = position;
    _sheet = sheet;
    _size = STARTING_SIZE;

    // Set the QGraphicsItem flags.
    setFlags(ItemIsMovable | ItemIsSelectable);

    // Get the true properties of the node.
    NameDefinition nodeDefinition;
    QByteArray nameByteArray      = name.toLatin1();
    const char *nameCharArray     = nameByteArray.constData();

    // THIS IS THE CALL TO THE COMPILED C FUNCTION
    NodeTrueProperties properties =
        d_semantic_get_node_properties(sheet, nameCharArray, 1, NULL,
                                       &nodeDefinition);

    // THIS FUNCTION DOES SOME WHACKY STUFF
    d_semantic_free_true_properties(properties);

    // ...
}

一切都编译得很好,但它根本运行不正常:

根据运行的 if 语句(因为传入的名称是 "Start"),我希望我的 NodeTrueProperties 看起来像这样:{true, false, true, NULL, 0, (pointer to DType array), 1}。根据调试器,我实际得到的是{true, false, false, NULL, 1, NULL, 0}

另一个非常奇怪的工件是在 C 代码中激活的 if 语句,尽管根据调试器的说法,条件是错误的 (trueProperties._mallocd == false):

我在Win32模式下使用CMake和VS2017将C项目编译成DLL,并使用Qt Creator和MSVC2017 32bit kit编译Qt C++项目。

【问题讨论】:

  • 我的猜测是,两个编译器在NodeTrueProperties 的二进制布局上不一致。尝试在 C 和 C++ 端打印 sizeof(NodeTrueProperties)bool 是 C++ 中的内置类型,但是 C 中的一些宏,可能扩展为不同大小的类型。

标签: c++ c qt debugging linker


【解决方案1】:

试试这个格式:@ #include &lt;dsemantic.h&gt; @ 我希望这有助于解决您的问题。

【讨论】:

    【解决方案2】:

    感谢 Igor Tandetnik 的评论,我找到了罪魁祸首:我在 C 库中创建的 bool(4 字节 = int)与 C++ 程序中的 bool 类型(1 字节)的大小不同,我认为最终也会更改程序和库之间的 NodeTrueProperties 结构。

    作为参考,我在 C 中更改了我的 bool 定义:

    /**
     * \enum bool
     * \brief A boolean.
     */
    typedef enum {
        false, ///< `false`
        true   ///< `true`
    } bool;
    

    包含stdbool.h 头文件:

    #include <stdbool.h>
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-05-12
      • 2022-01-25
      • 1970-01-01
      相关资源
      最近更新 更多