Можно ли включить заголовок C, используя атомарность C11, без изменений в C ++?

Я пытаюсь написать использовать эта библиотека C без изменений в приложении C ++. Он использует атомарность C11.

Рассмотрим следующую программу, которую мы можем поместить в файл с именем main.cc,

#include "mpscq.h"

int main(){}

Если я скомпилирую это с g++ -std=c++11 -c main.ccЯ получаю целую коллекцию ошибок, которые выглядят следующим образом.

usr/lib/gcc/x86_64-linux-gnu/4.9/include/stdatomic.h:68:9: error: ‘_Atomic’ does not name a type
typedef _Atomic __UINT_FAST32_TYPE__ atomic_uint_fast32_t;
^
/usr/lib/gcc/x86_64-linux-gnu/4.9/include/stdatomic.h:69:9: error: ‘_Atomic’ does not name a type
typedef _Atomic __INT_FAST64_TYPE__ atomic_int_fast64_t;

Можно ли исправить эти ошибки без каких-либо изменений в коде библиотеки?

То есть я готов использовать все магические заклинания, необходимые в моем коде c ++ или в флагах моего компилятора, но я бы не стал менять код библиотеки.

я видел этот ответ но это требует модификации файла заголовка.

5

Решение

Можно ли исправить эти ошибки без каких-либо изменений в коде библиотеки?

C ++ не имеет _Atomic квалификатор типа, но структура, объявленная в заголовке библиотеки, имеет члены, включая первый, с _Atomicквалифицированный тип. C ++ не примет это (и обернуть включение заголовка в extern "C" блок не поможет).

С позволяет объектам _Atomicквалифицированный тип, чтобы иметь представления, отличные от объектов_Atomic версия того же типа, так что в общем смысле это означает, что C ++ не может получить прямой доступ ни к каким членам любого экземпляра этой структуры.

Если ваша реализация C использует то же представление для соответствующего _Atomic и не_Atomic типы, то вы, вероятно, могли бы заставить свой компилятор C ++ принимать заголовок с помощью #defineсимвол _Atomic в пустую строку, но это будет воротами к более тонким ошибкам. Вы не могли ожидать, что C ++ обеспечит семантику атомарного доступа, которую ожидает библиотека, поэтому даже в этом случае C ++ не может безопасно получить доступ к членам структуры (напрямую).

Если этого достаточно для манипулирования экземплярами struct только через предоставленные функции, тогда вы можете сделать это через непрозрачные указатели. Создайте версию заголовка, которая обеспечивает предварительное объявление структуры, но без определения, и которая обеспечивает все объявления функций (с привязкой C). Ваш код C ++ должен принимать заголовок и иметь возможность вызывать функции, получая и возвращая указатели на экземпляры структуры, которые он никогда не должен пытаться разыменовать.

#ifndef __MPSCQ_H
#define __MPSCQ_H

#ifdef __cplusplus
extern "C" {
#endif

struct mpscq;

struct mpscq *mpscq_create(struct mpscq *n, size_t capacity);
// other functions ...

#ifdef __cplusplus
}
#endif

#endif

Если вам нужно больше, чем предоставляют существующие функции, вам нужно написать дополнительные вспомогательные функции на языке C.

4

Другие решения

Вам не нужна оболочка для использования этого mpscq в коде C ++, но вам нужны другие
заголовок, чтобы включить его. Это будет работать:

#ifndef MPSCQ_H_FOR_CPP
#define MPSCQ_H_FOR_CPP

extern "C"{
struct mpscq;

mpscq *mpscq_create(mpscq *n, size_t capacity);

bool mpscq_enqueue(mpscq *q, void *obj);

void *mpscq_dequeue(mpscq *q);

size_t mpscq_count(mpscq *q);

size_t mpscq_capacity(mpscq *q);

void mpscq_destroy(mpscq *q);
}

#endif

Тем не менее, я в любом случае напишу обертку, чтобы позаботиться о RAII и тому подобное.

5

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector