0

First, I've been coding in C# for a few years now, and it's been a long time since I've written any C code. I'm using Visual Studio 2013. I am working on a sample program for an API product my company makes. Most of the program is in one source file & 1 header file. The program has to parse XML, which is returned by the API calls. Showing how to parse XML is not the point of the sample, so I decided the program would define a simple function called GetXmlValue in order to hide the XML parsing details. I defined this function in the main .C file like this:

//---------------------
// XML processing function forward declaration
// Note that the implementation of this functions is outside the scope of this program.  You must implement it yourself
// using a real XML library.
//---------------------

// This function must return a value indicating the number of characters that were copied into the buffer.
// If no characters were copied, the return value should be zero.  It's OK if the function returns a negative value
// to indicate that the XPath could not be found.

extern int GetXmlValue(char *xml, char *xpath, char *buffer, int bufferSize);

Then, in a separate file called ParseFunction.c, I implemented the function. Everything compiles without error, but I'm getting an "unresolved external symbol" link error:

error LNK2019: unresolved external symbol "int __cdecl GetXmlValue(char *,char *,char *,int)" (?GetXmlValue@@YAHPAD00H@Z) referenced in function "int __cdecl parseCommandType(char *)" (?parseCommandType@@YAHPAD@Z) C:...\LPRSDK_Sample\Sample\Sample.obj

As an experiment, I commented out the line in the function where the error was reported, to see if there was something wrong with that particular line, and the error just moved to the next function where the function was called.

If I move the code for the function into the sample program's C file, everything compiles and links. So it's probably something in my link settings, but I'm not familiar enough with the whole VS 2013 C language settings to even know where to look.

I did check the log file and I see the .obj file for both source files is included, so I don't understand why I'm getting the unresolved external symbol error at all. What have I done wrong?

4
  • 1
    Are you sure the ParseFunction.o (or .obj) gets linked to your main file? Commented May 26, 2015 at 13:10
  • The function is defined in a .c file, and the log file shows both .obj files are included in the link command. Regarding a separate ParseFunction.h, I tried that, too, without any luck. Commented May 26, 2015 at 13:11
  • If it's not a big project with many files, please try to rebuild the complete project and post the complete build-log in your question. Commented May 26, 2015 at 13:14
  • 1
    Either calls to your function and the function itself are compiled in different modes (possibly one as C, another one as C++ language) so the linker doesn't find a mangled function symbol ?GetXmlValue@@YAHPAD00H@Z or the module is not linked properly (so the linker doesn't find the symbol). Commented May 26, 2015 at 13:17

1 Answer 1

0

I found it. A co-worker suggested something and he was on the right track.

I moved the extern function's declaration up so it occurred before any typedefs, then put it inside of an "extern "C" block, like this

extern "C" {
    int GetXmlValue(char *xml, char *xpath, char *buffer, int bufferSize);
}

and now everything compiles and links correctly.

Sign up to request clarification or add additional context in comments.

2 Comments

Then the function is called from C++ code. C++ have name mangling which makes the function names include things like argument count and types, so the actual C code symbol (without mangling) can't be found. What extern "C" does in C++ (it will give you errors when compiling with a C compiler) is to turn of the name mangling for the symbol.
I moved the closing curly brace so the entire file, minus the #defines and #includes in it, is inside the extern "C" block. Everything still compiles. I tried changing the "C/C++ | Advanced | Compile As" option to "Compile as C code" and that <b>didn't</b> work, so I put the 'extern "C"' block back. Thanks for the help.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.