Это то, что делает меня довольно озадаченным.
У меня есть файл C ++, который реализует набор функций, и файл заголовка, который определяет прототипы для них.
При сборке с помощью Visual Studio или MingW-gcc я получаю ошибки связывания двух функций, и добавление квалификатора 'extern "C" устраняет ошибку. Как это возможно?
Заголовочный файл, "some_header.h":
// Definition of struct DEMO_GLOBAL_DATA omitted
DWORD WINAPI ThreadFunction(LPVOID lpData);
void WriteLogString(void *pUserData, const char *pString, unsigned long nStringLen);
void CheckValid(DEMO_GLOBAL_DATA *pData);
int HandleStart(DEMO_GLOBAL_DATA * pDAta, TCHAR * pLogFileName);
void HandleEnd(DEMO_GLOBAL_DATA *pData);
Файл C ++, "some_implementation.cpp"
#include "some_header.h"
DWORD WINAPI ThreadFunction(LPVOID lpData) { /* omitted */ }
void WriteLogString(void *pUserData, const char *pString, unsigned long nStringLen) { /* omitted */ }
void CheckValid(DEMO_GLOBAL_DATA *pData) { /* omitted */ }
int HandleStart(DEMO_GLOBAL_DATA * pDAta, TCHAR * pLogFileName) { /* omitted */ }
void HandleEnd(DEMO_GLOBAL_DATA *pData) { /* omitted */ }
Реализации компилируются без предупреждений, но при связывании с кодом пользовательского интерфейса, который их вызывает, я получаю нормальный
error LNK2001: unresolved external symbol "int __cdecl HandleStart(struct _DEMO_GLOBAL_DATA *, wchar_t *)
error LNK2001: unresolved external symbol "void __cdecl CheckValid(struct _DEMO_MAIN_GLOBAL_DATA *
Что меня действительно смущает, так это то, что только эти две функции (HandleStart и CheckValid), по-видимому, построены с использованием C-связи. Явное добавление объявлений "extern 'C'" только для этих двух исправило ошибку компоновки, и приложение собирается и запускается.
Добавление "extern 'C'" к какой-либо другой функции, такой как HandleEnd, вводит новую ошибку компоновки, так что она явно компилируется правильно.
Файл реализации никогда не модифицируется, только прототипы.