Большинство компиляторов C ++ обрабатывают как файлы исходного кода C, файлы с расширением. c, так и файлы исходного кода C ++, файлы с расширением. cpp. Поэтому первым шагом в преобразовании будет переход на компилятор C ++ и приведение файлов вашего проекта и / или создание файлов в порядок, чтобы все это компилировалось.
Следующее - go через исходный код кодовая база, чтобы определить, какие структуры данных будут изменены и какие файлы, обычно файлы с расширением .h, имеют эти структуры данных, которые нужно будет изменить.
На этом этапе вам нужно будет начать разбиение что такое источник C ++ и какой источник C. Например, в то время как C struct
является подмножеством C ++ struct
, C ++ struct
допускает конструкторы и деконструкторы, которые C не позволяет. Это означает, что вы можете использовать C struct
с исходным кодом C ++, но нельзя использовать C ++ struct
с функциями C ++ в исходном файле C.
Другие ключевые слова языка C ++, такие как class
просто не будет работать с исходным кодом C.
Далее стоит посмотреть, какие функции C ++, такие как шаблоны и функции стандартной библиотеки C ++, такие как std::string
, вы собираетесь использовать. Опять же вам нужно будет отделить исходный код C ++ от C.
Функциональность extern "C"
позволяет вам использовать функции C с исходным кодом C ++, объявив имя функции или переменной как C а не C ++. Это необходимо, потому что компилятор C ++ выполняет искажение имен, используя алгоритм для генерации измененного имени для функций, допускающих перегрузку функций. См. Что такое искажение имен и как оно работает?
Еще одна вещь, с которой вы столкнетесь, это то, что C ++ представил новые версии большинства стандартных C включаемых файлов без расширение .h. Вы можете использовать старую версию с C ++, но новые версии предпочтительнее, поскольку они предназначены для C ++. Однако C исходные файлы могут использовать только старую версию этих файлов с расширением .h.
Условная компиляция для заголовочных файлов
Волхвы c, которые позволяет использовать более старый стандарт C, включающий файлы с исходным кодом C ++, так как большинство компиляторов имеют специальный #define
, который можно использовать для условной компиляции. С компилятором Visual Studio специальное определение - __cplusplus
, и его можно использовать примерно так:
#if defined(__cplusplus)
extern "C" {
#endif
// The type CONNENGINEHANDLE is for future expansion to allow multiple
// sockets to be managed by the dll.
typedef unsigned short CONNENGINEHANDLE;
// following functions are used with a server implementation.
// these functions will setup the parameters for the server and
// start the listen needed to accept a connection from a client
CONNENGINE_API int fnConnEngineSetDomainNamePort(CONNENGINEHANDLE hConnEngineSocket, char *aszDomainName, int nPortNo);
CONNENGINE_API int fnConnEngineStartEngine (int nPort, HWND hWinHandle, UINT wReceiveMsgId);
CONNENGINE_API int fnConnEngineStopEngine ();
#if defined(__cplusplus)
};
#endif
Что делает вышеуказанный код препроцессора, являющийся частью включаемого файла, так это разрешить файл исходного кода C ++ чтобы включить тот же заголовочный файл, что и файлы исходного кода C, но когда он включен в файл C ++, extern "C" {
является частью текста заголовочного файла, поскольку препроцессор определил __cplusplus
. Таким образом, источник C ++ может использовать функции, определенные в исходном коде C, и искажение имени, обычно выполняемое с помощью C ++, отключено для тех функций, объявления которых заключены в фигурные скобки.
Однако, хотя это специальное #define
чтобы определить, обрабатывается ли препроцессором исходный файл C ++, вы все еще не можете использовать языковые конструкции C ++ в C исходных файлах. Вам все равно нужно будет отделить C ++ от C.
Интерфейсных функций для C вызова функции C ++
В некоторых случаях вам может потребоваться выполнить Функциональность исходного кода C ++ из C функциональность исходного кода. В этих случаях вам потребуется создать C совместимый интерфейс с функциями C ++.
Например, если у вас есть struct
, который содержит std::string
, что несовместимо с исходным кодом C Вы можете создать исходный код C ++, чтобы скрыть детали реализации и затем предоставить C совместимый интерфейс.
Например, из примера включаемого файла, демонстрирующего использование __cplusplus
выше, одна из этих функций определяется в файле исходного кода C ++ следующим образом. Этот файл исходного кода C ++ также содержит тот же заголовочный файл, который будет использоваться с файлом исходного кода C и с объявлением выше для функции fnConnEngineStartEngine()
, компилятор C ++ знает, что он не должен называть mangle имя функции fnConnEngineStartEngine{}
. Этот исходный код C ++ обеспечивает интерфейс между источником C, который использует объект C ++ theApp
.
CONNENGINE_API int fnConnEngineStartEngine (int nPort, HWND hWinHandle, UINT wReceiveMsgId)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
if (hWinHandle == 0)
hWinHandle = theApp.m_hWinHandle;
if (wReceiveMsgId == 0)
wReceiveMsgId = theApp.m_wReceiveMsgId;
theApp.StartEngineAsServer (nPort, hWinHandle, wReceiveMsgId);
return 0;
}