【问题标题】:How do I share variables between C and C++ code?如何在 C 和 C++ 代码之间共享变量?
【发布时间】:2023-03-17 15:23:01
【问题描述】:

我正在开发一个实现 C 代码的 C++ 项目,但遇到了分段错误。当我尝试访问 C++ 代码中的全局 C 变量时,会发生段错误。

代码概览:
我有一个名为 video_stage.c 的 c 文件,其中包含以下代码 sn-p:

#include "video_stage.h"

uint8_t*  pixbuf_data = NULL;    //pointer to video buffer
vp_os_mutex_t  video_update_lock = PTHREAD_MUTEX_INITIALIZER;  

C_RESULT output_gtk_stage_transform( void *cfg, vp_api_io_data_t *in, vp_api_io_data_t *out)
{
   vp_os_mutex_lock(&video_update_lock);

   /* Get a reference to the last decoded picture */
   pixbuf_data      = (uint8_t*)in->buffers[0];

   vp_os_mutex_unlock(&video_update_lock);
   return (SUCCESS);
}

此函数由其他 C 代码定期调用,并更新指向 RGB 视频帧的 pixbuf_data 指针。

是头文件video_stage.h:

#ifndef _IHM_STAGES_O_GTK_H
#define _IHM_STAGES_O_GTK_H

#ifdef __cplusplus
extern "C" {
#endif

#include <config.h>
#include <VP_Api/vp_api_thread_helper.h>
#include <VP_Api/vp_api.h>                  //hier zit vp_os_mutex in geinclude

PROTO_THREAD_ROUTINE(video_stage, data);

#ifdef __cplusplus
}
#endif

extern uint8_t*  pixbuf_data;
extern vp_os_mutex_t  video_update_lock;

#endif // _IHM_STAGES_O_GTK_H

头文件包含 pixbuf_data 指针的 extern 声明。

这里是 cpp 文件:device.cc:

#include <iostream>
#include "video_stage.h"

int ardrone_update(ardrone_t *d)
{
    uint8_t x;

    x = pixbuf_data[0];            //no problem here, this is executed
    std::cout << 5 << std::endl;   //this is executed too
    std::cout << x << std::endl;   //segfault occures here

}

当 cpp 文件中的函数被调用(由其他 cpp 代码)时,在打印 x 的 cout 指令处发生段错误。

当我对 c 文件中缓冲区的第一个元素执行 printf 时,我得到了我期望的结果。

我确信这与混合 c 和 c++ 代码有关,但根据我的研究,我已经完成了使 c 和 c++ 代码兼容的工作。

【问题讨论】:

  • 问“我如何在没有段错误的情况下做 XYZ”是没有意义的。如果你得到一个段错误,你写了一个错误的程序,所以这就像问“我如何做 XYZ 而不做错?”这与“我该如何做 XYZ?”是一样的。
  • 发生段错误时,您是否真的打印了“5”?您是否尝试检查为 ardrone_update 函数生成的汇编代码(尝试使用带有 -S 选项的 gcc/g++)?

标签: c++ c segmentation-fault


【解决方案1】:

在 C 源代码中定义的 C++ 代码 pixbuf_data 必须使用 C 链接声明:

extern "C" uint8_t*  pixbuf_data;

没有extern "C",C++ 代码不得链接,除非有另一个(重复的)pixbuf_data 定义与 C++ 链接。

【讨论】:

  • 我认为extern "C" 只会对功能产生影响。 C++ 会破坏变量的名称吗?
  • C++ 也会混淆变量名称,因为它需要为静态变量混合变量命名空间名称或类名称。
  • 嗯,我的编译器 (gcc) 不适用于我检查过的全局范围内的名称。据我了解,OP 有一个完全链接的程序,所以这不是问题,也没有回答问题。
  • @JensGustedt:我检查过,你是对的,gcc 不会破坏 C++ 翻译单元中定义的全局变量。这就解释了为什么它链接。迂腐地,根据 C++ 标准,它仍然是未定义的行为。无论如何,这一定是另一个问题导致了这里的段错误。
  • 确实很奇怪,有人回到那个非常古老的问题并且没有什么比否决它更好的事情了。也许问题标题吸引了希望在这里找到更多信息的人。如果他是常客,OP 可能会接受我的回答,至少他说这解决了他的问题。但这并不会降低您的回答的价值。
【解决方案2】:

给自己一个调试器并在它下面运行你的程序。跟踪代码根本没有告诉你段错误出现在哪里,IO 很慢。

在您向我们展示的代码中,您似乎没有为pixbuf_data 分配内存。当您在没有为其分配有效指针的情况下访问它时,任何事情都可能发生。

【讨论】:

  • 好吧,我猜你给了我解决方案。 Pixbuf 有一个可以指向的有效位置,但该位置仅在一段时间后才有效:函数 ardrone_update 在程序开始时的 output_gtk_stage_transform 之前被调用(多线程程序)。现在问题解决了:)
【解决方案3】:

我正在尝试在 C 项目和 C++ 项目之间共享变量。但是当我构建我的解决方案时,我得到了“错误 LNK2001:无法解析的外部符号“结构配置 g_conf”。这就是我所做的:

==== 在 C 项目中 ==

我创建一个头文件并在上面创建我的结构

typedef struct{ int maxUser; }Configuration;
extern Configuration conf;

==== 在 C++ 项目中 =======

在主文件中:

#include "../ProjectC/header.h"

int main(){ conf.maxUser = 10; }

【讨论】:

    猜你喜欢
    • 2011-03-09
    • 2012-10-27
    • 2013-07-26
    • 1970-01-01
    • 2018-04-25
    • 2011-09-14
    • 1970-01-01
    • 2015-03-28
    • 1970-01-01
    相关资源
    最近更新 更多