Использовать библиотеку C в коде C ++ с несовместимым кодом - PullRequest
5 голосов
/ 13 мая 2019

Я хочу использовать библиотеку C в коде C ++, не изменяя ее.

Библиотека содержит фрагмент кода, несовместимый с c ++, например:

  • ключевое слово C ++ new и delete
  • _Atomic объект
  • плохая декларация

Я скомпилировал библиотеку C в .so. И я также использовал его в другом C-коде, и он работал отлично (на самом деле я хочу сделать C ++-версию этого кода).

Мои CMakeLists:

# Specify the minimum CMAKE version required
cmake_minimum_required(VERSION 2.8)

# Project name
project(myproject)

# Header files
set(HEADERS myCpp.h)

# Source files
set(SOURCES myCpp.cpp)
add_executable(myproject myCpp.cpp myCpp.h)

# Link libraries
LINK_DIRECTORIES(/usr/lib/libfrr.so)
target_link_libraries(${PROJECT_NAME}  frr)


set_target_properties(${PROJECT_NAME} PROPERTIES LINKER_LANGUAGE C)

set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11" )
set(CMAKE_CXX_FLAGS "-fpermissive")

Мой заголовок начинается с:

extern "C"{
        #include "lib/libfrr.h"
}

У меня куча ошибок. Небольшая подборка:

/lib/module.h:88:3: error: expected primary-expression before '.' token
   .r.info = &_frrmod_info,        

/lib/thread.h:123:2: error: '_Atomic' does not name a type
  _Atomic unsigned int total_active;

lib/memory.h:163:13: error: 'struct memtype' has no member named     'n_alloc'
  return mt->n_alloc;

/lib/libfrr.h:88:25: sorry, unimplemented: non-trivial designated     initializers not supported
          __VA_ARGS__};           \

1 Ответ

8 голосов
/ 13 мая 2019

Простое (хотя, возможно, не единственное) решение:

Напишите тонкую прокладку привязки C ++ для вашей библиотеки C.

Поскольку ваша библиотека содержит код C, которыйне совместим с C ++ - не входит в общее подмножество обоих языков - вы должны написать привязки, которые C ++ может использовать.Они должны быть написаны на C, а не на C ++ .

Давайте назовем файлы привязки, которые вы пишете, frr_cpp_bindings.h и frr_cpp_bindings.c.

Файл заголовка shim, frr_cpp_bindings.h, будет по существу представлять то же самое, что и libfrr.h, но без какого-либо фактического кода (например, ./r.inf = &_frrmod_info) - только определения функций и типов, которые находятся в общем подмножествеC ++ и C.

Реализация этого shim (frr_cpp_bindings.c) будет включать libfrr.h напрямую и в основном просто перенаправлять вызовы к libfrr.h -объявленным функциям C.

Наконец, вВ файле frr_cpp_bindings.h вы можете получить что-то вроде этого:

#ifdef __cplusplus
extern "C" {
#endif

// all of the actual C code

#ifdef __cplusplus
}
#endif

, и это означает, что вам не нужно extern "C" в коде C ++.

Наконец, ваш C ++исходные файлы будут иметь:

#include <frr_cpp_bindings.h>

и не будут пытаться напрямую включить несовместимый заголовок.

...