У меня есть набор классов C++, объекты которых управляются в простом файле C++. Для этого файла у меня есть файл заголовка. К некоторым API-интерфейсам я хочу получить доступ из модуля C, а к некоторым из модуля C++. Любые предложения, как я могу этого добиться?
Чтобы опробовать этот подход, я написал следующие файлы.
Мой основной класс и его реализация (myclass.h и myclass.cpp):
myclass.h
#ifndef _MY_CLASS_H
#define _MY_CLASS_H
#include<iostream>
#include<string>
class MyClass
{
public:
MyClass();
~MyClass();
void setServer(std::string url);
void printServer();
private:
std::string serverURL;
};
#endif
myclass.cpp
#include "myclass.h"
MyClass::MyClass()
:serverURL("")
{
}
MyClass::~MyClass()
{
}
void MyClass::setServer(std::string url)
{
serverURL = url;
}
void MyClass::printServer()
{
if (serverURL == "") {
std::cout << "Server URL is empty\n";
} else {
std::cout << "Server URL : " << serverURL << std::endl;
}
}
Теперь написана оболочка, использующая указанный выше класс. Цель состоит в том, чтобы предоставить два API init () и uninit () модулю C, а остальные два - модулю C++.
wrappe.h
#ifndef _WRAPPER_H
#define _WRAPPER_H
#include<string>
#ifdef __cplusplus
extern "C" {
#endif // __cplusplus
// APIs that are exposed to C module(s)
void init();
void uninit();
#ifdef __cplusplus
}
#endif // __cplusplus
// C++ APIs exposed to C++ modules
#ifdef __cplusplus
void setServer(std::string url);
void printS();
#endif // __cplusplus
#endif // _WRAPPER_H
wrapper.cpp
#include "myclass.h"
static MyClass *myClass = 0;
void init()
{
myClass = new MyClass();
}
void uninit()
{
if (myClass != 0) {
delete myClass;
}
}
void setServer(std::string url)
{
myClass->setServer(url);
}
void printS()
{
if (myClass != 0) {
myClass->printServer();
}
}
Вот файлы модуля C, которые обращаются к API C.
backend.h
#ifndef _BACKEND_H
#define _BACKEND_H
#ifndef __cplusplus
extern "C" {
#endif
void backend_init();
void backend_uninit();
#ifndef __cplusplus
}
#endif
#endif
backend.c
#include "wrapper.h"
#include "backend.h"
void backend_init()
{
init();
}
void backend_uninit()
{
uninit();
}
Вот файлы модуля C++, которые вызывают API wrapper.h
guiuser.h
ifndef _GUIUSER_H
#define _GUIUSER_H
void gui1();
void gui2();
#endif
guiuser.cpp
#include "wrapper.h"
void gui1()
{
setServer("localhost");
}
void gui2()
{
printS();
}
Вот главный файл, который вызывает API модуля.
main.cpp
#include "guiuser.h"
#include "backend.h"
#include "wrapper.h"
int main()
{
backend_init();
gui1();
gui2();
backend_uninit();
}
Сбой компиляции для backend.c wrapper.h: 4: 17: фатальная ошибка: строка: нет такого файла или каталога компиляция прекращена.
Стоит ли разбивать wrapper.h на две части? Один для включения в бэкэнд и один для включения в guiuser?
Есть еще предложения по дизайну?
компилятор gcc или g ++?
molbdnilo - Ваш намек был полезен, и Р. Саху предоставил точное решение ошибки. Кроме того, была еще одна ошибка в wrapper.cpp. Мне пришлось включить wrapper.h в wrapper.cpp. С этими двумя изменениями я смог успешно скомпилировать и связать программу.





<string> - это заголовок только для C++. Окружите строку #include <string> той же логикой препроцессора, которую вы используете для setServer.
#ifdef __cplusplus
#include <string>
#endif
Присмотритесь к тому месту, где вы положили этот
#include<string>.