如何在C和C++代码之间共享变量?

3

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

代码概述:
我有一个名为video_stage.c的单个c文件,其中包含以下代码片段:

#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代码周期性地调用,并更新pixbuf_data指针,该指针指向一个RGB视频帧。

它的头文件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++代码兼容的工作。


4
问:“如何在不出现segfault的情况下执行XYZ操作”是毫无意义的。如果出现segfault,那么你写了一个错误的程序,这就像是在问“如何在不做错的情况下执行XYZ操作?”而这与“如何执行XYZ操作?”是一样的。 - Kerrek SB
当发生段错误时,您是否实际上会得到“5”打印出来?您是否尝试检查ardrone_update函数生成的汇编代码(可以使用gcc/g++的-S选项进行尝试)? - Tomek
3个回答

3
在C++代码中,必须使用C链接方式声明在C源文件中定义的pixbuf_data
extern "C" uint8_t*  pixbuf_data;

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

我认为 extern "C" 只会对函数有影响。C++ 会改变变量的名称吗? - Jens Gustedt
2
C++也会混淆变量名,因为它需要将变量命名空间或类名混合到静态变量中。 - Maxim Egorushkin
3
嗯,我的编译器(gcc)似乎不能处理全局作用域中的名称,我进行了检查。就我所理解的而言,OP拥有一个完整链接的程序,因此这不可能是一个问题,也不能回答这个问题。 - Jens Gustedt
1
@JensGustedt:我已经检查过了,你是对的,'gcc'不会混淆C++翻译单元中定义的全局变量。这就解释了为什么可以链接。严谨地说,根据C++标准,这仍然是未定义行为。无论如何,在这里导致段错误的必须是另一个问题。 - Maxim Egorushkin
1
确实很奇怪,有人回到那个非常老的问题,并且除了给它投反对票之外没有更好的事情可做。也许问题标题吸引了人们,他们期望在这里找到更多的东西。如果他是一个常客,原帖作者可能会接受我的答案,至少他说它解决了他的问题。但这并不会使你的答案不值得。 - Jens Gustedt

1

获取一个调试器并在其中运行程序。跟踪代码根本无法告诉您段错误出现的位置,IO速度很慢。

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


嗯,我猜你给了我解决方案。Pixbuf 有一个有效的指向位置,但那个位置只有在一段时间后才有效:在程序开始时调用 ardrone_update 函数之前调用 output_gtk_stage_transform 函数(多线程程序)。问题现在已经解决 :) - martin

0
我正在尝试在C项目和C++项目之间共享变量。但是当我构建我的解决方案时,我收到了“错误LNK2001:未解析的外部符号”struct configuration g_conf"。这是我所做的:
==== 在C项目中 ==
我创建了一个头文件,并在其中创建了我的结构体。
typedef struct{ int maxUser; }Configuration;
extern Configuration conf;

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

在主文件中:

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

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接