4

Trying to figure out how to get an application to compile that uses both C and C++ files. Not the entire code, but enough to get the idea:

main.cpp:

#include <windows.h>
#include <stdio.h>
#include <string.h>
#include "one.h"
#include "two.h"

int __stdcall WinMain(HINSTANCE hInst, HINSTANCE hInst2, LPSTR lpCmdLine, int nShowCmd) {
    FunctionOne();
    FunctionTwo();
}

one.cpp:

#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include <gdiplus.h>
#include <gdiplusflat.h>
using namespace Gdiplus;
using namespace Gdiplus::DllExports;

int FunctionOne() {
}

two.c

#include <stdio.h>
#include <stdlib.h>
#include <windows.h>

int FunctionTwo() {
}

The header files contain only definitions for those functions.

Now, if I compile this with a main.cpp, I get an "unresolved external symbol" for FunctionTwo. If I compile this with a main.c, I get the same thing for FunctionOne. Is this even possible, and if so, how would I set up the project to compile properly (Visual Studio 2010)?

It compiles fine if I comment out the alternate function depending on the extension for main.

Thanks!

Hans Passant
  • 922,412
  • 146
  • 1,693
  • 2,536
Fmstrat
  • 1,492
  • 2
  • 17
  • 24
  • See this -> http://stackoverflow.com/questions/12573816/what-is-an-undefined-reference-unresolved-external-symbol-error-and-how-do-i-fix/12574420#12574420 - MSVS compiles `.c` files as C and `.cpp` files as C++. – Luchian Grigore Sep 27 '12 at 21:25

2 Answers2

11

The problem is two.h, it almost certainly wasn't written to allow a C++ compiler to properly compile the C function prototype. You'll want to take advantage of the predefined __cplusplus macro, like this:

two.h:

#ifdef __cplusplus
extern "C" {
#endif

int FunctionTwo();
// etc...

#ifdef __cplusplus
}
#endif

Lovely macro soup ;) If the header is pre-baked and never saw a C++ compiler before then do this in your .cpp source code file:

#include <windows.h>
#include <stdio.h>
#include <string.h>
#include "one.h"
extern "C" {
#include "two.h"
}

Some programmers name their header files .hpp if they contain C++ declarations and .h if they contain C declarations. That's a pretty good practice I personally favor. So does the Boost team. It didn't otherwise set the world on fire.

Hans Passant
  • 922,412
  • 146
  • 1,693
  • 2,536
  • Thank you for the response. This was marked as a duplicate, but I was unable to locate the other answer as it didn't focus on the wording of the question in my mind (C vs. C++ instead of the message itself). Your solution worked for me. – Fmstrat Sep 28 '12 at 03:35
0

C++ does name-mangling to support function overloading while C does not. You will have to mark your function as extern "C" to prevent name mangling.

// main.cpp

extern "C" int FunctionTwo();

.. the rest ..

// two.c

extern "C" int FunctionTwo() {
    // stuff
}

See http://www.parashift.com/c++-faq/mixing-c-and-cpp.html for more information on mixing C and C++.

Seth Carnegie
  • 73,875
  • 22
  • 181
  • 249