3

我正在开发一个用 C++ 编写的小型应用程序,并希望在我的平台上使用。不幸的是,我们的交叉编译工具链仅(可靠地)提供了 C 编译器。我查看了该应用程序,它相当简单,仅在少数地方使用了 C++ 特定的习惯用法,所以我想我只需手动将其转换为 C 代码即可。

我碰到了一条不知道如何处理的线。该代码使用 Termios 打开一个新端口与 TTY 流通信,并使用new关键字初始化 Termios 结构。

termios *settings = new termios();

据我了解,new关键字除了分配适当的内存外,还调用对象的初始化程序。在 C 中,使用 分配内存后malloc,我可以手动调用初始化程序吗?我需要吗?

我有一种感觉,我误解了一些明显/基本的东西,或者我认为这一切都是错误的。我不太习惯 C++ 代码。

编辑:我似乎引起了一些混乱。上面的代码行创建了一个新的 termios 结构,定义在 中termios.h,它是大多数 C 实现的标准库的一部分。

4

4 回答 4

3

线

termios *settings = new termios();

termios对象分配内存并对其进行值初始化。由于termios是 POD,因此等效 C 将是

struct termios* settings = calloc(1, sizeof(*settings));

或者

struct termios* settings = malloc(sizeof(*settings));
memset(settings, 0, sizeof(*settings));

当然等价delete settingsfree(settings).

于 2014-11-20T18:43:02.227 回答
1

我建议创建一个函数

termios *new_termios()

这会将 malloc 与构造函数代码结合起来。之后,不要使用 malloc 来分配termios.

于 2014-11-20T18:34:58.837 回答
1

“在C中,我用malloc分配内存后,可以手动调用初始化器吗?

不幸的是,你不能。

我需要吗?”

这实际上取决于termios对象的定义。基本上,malloc所做的只是分配一块内存。也就是说,它不像构造函数那样做任何初始化和内部内存分配。

在这些情况下我会做什么:

我在不透明指针的帮助下为我的 C++ 对象创建了 C 包装函数。例如,为了调用 C++ 对象的构造函数,我将在.cpp文件中为 C 创建一个 C++ 包装器:

void* create_termios() { return new termios(); }
void  destroy_termios(void *obj) { delete obj; }
// other wrapper functions for termios

然后我会在 C 中将这些函数与一个.h文件接口:

extern "C" {
    void* create_termios();
    void  destroy_termios(void *obj);
    // declare any other necessary wrappers
}
于 2014-11-20T18:35:01.130 回答
0

Notice that termios is the name of a struct related to termios(3) function, so better not use that termios name in a Linux or POSIX program in C (i.e. avoid naming your types with usual types provided by system libraries).

BTW you should consider using some existing terminal IO library like ncurses or readline

At last, if you insist in having your own termios structure or class (which is practically a very bad idea, choose some other name) managed by your C++ library to be called by C, you should wrap its allocator+constructor & destructor+deallocator like this.

extern "C" struct termios* make_my_termios () {
   struct termios* ts = new termios;
   return ts;
}

extern "C" void destroy_my_termios(struct termios* ts) {
   delete ts;
}

And if you just use the genuine struct termios* (from termios(3)) in your C++ library, just keep it as it is...

于 2014-11-20T18:33:40.573 回答