C++将对象创建为静态-良好实践所需的建议

  • 本文关键字:对象 创建 静态 C++ c++ c
  • 更新时间 :
  • 英文 :


我主要是一名C程序员,在Raspberry Pi上构建原型。我广泛使用了一些开源C代码,但也使用了带有C++驱动程序的Raspberry Pi硬件插件。所以我需要他们一起工作。我做了一些研究,通过编写一个带有外部"C"声明的C++函数,将其编译为共享库,并将其与我的C程序链接,使他们能够协同工作。

我需要C++函数在第一次调用对象时实例化它,然后在随后调用该函数时能够与该对象交互。关于如何在C中直接创建和访问C++对象的说明让我有点不知所措,所以我尝试在创建对象之前简单地添加"static",并通过C包装器的中介与对象交互。这似乎很完美,但我有点担心,这并不是"在C中使用C++对象"的常规答案,所以我想知道我是否会遇到不可预见的问题?在这个阶段,我不需要我的代码是高质量的,但我不想因为我做了一些愚蠢的事情而导致分割错误。任何建议都将不胜感激。

这是一个精简版来展示我在做什么。在这个例子中,我创建了一个简单的c++函数,它从调用c程序中获取一个int参数。如果参数为0,则创建对象并将数组中的所有LED设置为0。如果我用参数=1第二次调用它,它会指示同一个对象点亮所有的红色LED。此代码有效。

#include <string.h>
#include <matrix_hal/everloop.h>
#include <matrix_hal/everloop_image.h>
#include <matrix_hal/matrixio_bus.h>
extern "C" int led_change(int input_from_c)
{
namespace hal = matrix_hal;
static hal::MatrixIOBus bus;
static hal::EverloopImage image1d(18);
static hal::Everloop everloop;
if (input_from_c == 0)
{
if (!bus.Init()) return false;
// this line just resizes the EverloopImage object to the number of LEDs on the board
everloop.Setup(&bus);
// switch off the leds
for (int i=0;i<18;i++)
{
image1d.leds[i].red = 0;
image1d.leds[i].green = 0;
image1d.leds[i].blue= 0;
image1d.leds[i].white = 0;
}
everloop.Write(&image1d);
}
else if (input_from_c == 1)
{
for (int i=0;i<18;i++)
{
image1d.leds[i].red = 100;
image1d.leds[i].green = 0;
image1d.leds[i].blue= 0;
image1d.leds[i].white = 0;
}
everloop.Write(&image1d);
}
return 1;
}

C中的调用代码只是

#include  <unistd.h>
#include <stdio.h>
int led_change (int);
int i;
void main () {
i = led_change(0);
printf("returned %dn",i);
sleep(1);
i = led_change(1);
printf("returned second time %dn",i);
}

希望这个清楚。谢谢你的帮助。

您需要将所有C代码编译并链接为C++模块。反之无效。C不知道要为C++模块中的static对象调用的构造函数。。。因此链接器必须理解c++调用序列。C++语言的设计考虑到了旧C代码的兼容性。但C在设计时并没有考虑到这一点。

尽管如此,C++编译器通常也可以编译纯C代码(在C语言模式下(,因此其中一个编译器是有效的。它将生成可以在同一程序中生存而没有任何问题的代码。

您可以在C++程序中使用C代码main()函数,但始终使用C++链接器将该代码链接到程序中。

当"C"代码使用"extern"链接到C++代码时,C++编译器在对象文件中创建符号名称时,会停止对这些C变量或函数的"名称篡改"。对于C++函数,它们篡改名称以支持函数重载。

当静态对象从共享对象返回时,它们可能会在多线程程序中产生问题,比如两个或多个线程同时修改静态对象中的值。

最新更新