【问题标题】:C and C++ Code Interoperability - Data Passing IssuesC 和 C++ 代码互操作性 - 数据传递问题
【发布时间】:2011-10-21 01:24:18
【问题描述】:

以下是情况。有一个完全用 C 编写的系统/软件。这个 C 程序产生一个新线程来启动某种用 C++ 编写的数据处理引擎。因此,我拥有的系统运行 2 个线程(主线程和数据处理引擎线程)。现在,我用 C 语言编写了一些函数,它接收 C 结构并将其传递给数据处理线程,以便 C++ 函数可以访问 C 结构。这样做时,我观察到 C 结构中某些字段(如 unsigned int)的值在 C++ 端访问时会发生变化,我不知道为什么。同时,如果我传递像 int 这样的原始数据类型,则值不会改变。如果有人可以向我解释为什么它会这样,那就太好了。以下是我编写的代码。 `

/* C++ Function */
void DataProcessor::HandleDataRecv(custom_struct* cs)
{
  /*Accesses the fields in the structure cs - an unsigned int field. The value of   
    field here is different from the value when accessed through the C function below.
   */
}

/*C Function */
void forwardData(custom_struct* cs)
{
  dataProcessor->HandleDataRecv(cs); //Here dataProcessor is a reference to the object 
                                     //of the C++ class.
}

` 此外,这两个函数都在不同的源文件中(一个带有 .c ext,另一个带有 .cc ext)

【问题讨论】:

  • 您在哪个平台上运行您的代码?哪个编译器/链接器系列?
  • 我在 linux 上运行我的代码并使用 gcc 编译 C 和 C++ 文件
  • 另外,请出示相关代码。我怀疑这是thiscall 约定的问题,但这只是一种直觉。除非我看到代码,否则我无法验证。
  • unsigned int 可能是原语,但包含unsigned int 的结构肯定不是,这就是他区分的地方。我在这里的猜测是,它与 C 函数并不像他首先想到的那样可重入有关,但这只是猜测。正如其他人所说,没有看到代码,我们就在黑暗中刺伤。
  • 所以你的意思是,你的 C++ 函数看到的结构与你的 C 函数不同,即使你可以保证结构是相同的?是否有可能其他线程正在修改调用之间的结构?

标签: c++ c interop


【解决方案1】:

我会检查双方是否在同一个结构中布局

  • 以两种语言打印sizeof(custom_struct)
  • 在两种语言中创建一个 custom_struct 实例并打印 每个成员变量。

【讨论】:

  • 谢谢迈克尔。我会试试看。
【解决方案2】:

我的疯狂猜测是 Michael Andresson 是对的,结构对齐可能是问题所在。

尝试同时编译 c 和 c++ 文件

-fpack-struct=4

(或 4 的其他数字)。这样,结构在每种情况下的对齐方式都是相同的。

如果我们能看到结构声明,它可能会更清楚。该结构不包含任何带有 c++ 特定代码(如构造函数)的#ifdef,是吗?另外,检查#pragma pack 操作数据对齐的指令。

【讨论】:

    【解决方案3】:

    也许在结构的一侧添加了“空字节”以使变量在 32 位边界上对齐以提高速度(因此 CPU 寄存器可以直接指向变量)。

    另一方面,结构体可能会被打包以节省空间。

    【讨论】:

    • 在这种情况下,如果我创建一个新结构并通过一些包装器将 C 结构转换为这个结构,那会起作用吗?
    • 我会首先确定这是否是问题所在。大多数编译器都有开关或编译指示来打开和关闭字节打包。你也可以通过添加虚拟变量来手动布局你的结构体。
    【解决方案4】:

    (更正)除了少数例外,C++ 是 C(意思是 C89)的超集,所以我对正在发生的事情感到困惑。我只能假设它与您传递或输入变量的方式和/或它们运行的​​系统有关。从技术上讲,除非我弄错了,否则它应该与 c/c++ 互操作性无关。

    更多细节会有所帮助。

    【讨论】:

    • C 不是 C++ 的严格子集。例如,C99 的许多特性没有进入 C++。
    • 我在 linux 系统上运行并使用 gcc 编译器编译了两个 C/C++ 源文件。基本上,我通过 C 包装函数将 C 结构传递给 C++ 函数,该函数调用 C++ 函数。 C++ 函数只访问这个结构的成员。
    • 值如何变化,即,您是否注意到任何可辨别的模式,是完全随机的....... 结构类型是什么,您确定它们包含您认为它们包含的内容,以及c++ 函数用它们做什么。
    猜你喜欢
    • 2013-01-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-01
    • 1970-01-01
    相关资源
    最近更新 更多