27

I've got a weird linker issue. I have code that looks like so:

    double given_amount = self.modelController.levelCompleteRewardAmount;
    swrve_currency_given(swrve, (CFStringRef)@"currencyName", given_amount);

I have this code in two separate places: In an objective-c and an objective-c++ file. It compiles fine in objective-C land, but the swrve_currency_given() function causes the following in my WGController.mm file:

Undefined symbols for architecture armv7:
  "swrve_currency_given(Swrve*, __CFString const*, double)", referenced from:
      -[WGController giveTheUserSomeCashForPlayingThisLevel] in WGController.o
ld: symbol(s) not found for architecture armv7
collect2: ld returned 1 exit status

I'm not entirely sure if this error is related to the Obj-C vs. C++ thing, but it feels like it. My theory is that it perhaps thinks that it is a function on the Obj-C class? The 'swrve' code is 3rd party code, one .h and .c file and I'm importing like so:

#import "swrve.h"

Any help is appreciated! Thanks

2
  • Are you also importing it in the project for the linker? Go to the properties of your target, and open "Linked Frameworks and Libraries" on the summary page. The swrve library should be there; if it is not, add it and try compiling again. Commented Feb 17, 2012 at 20:07
  • The library isn't a static lib/framework, it is just a .c and .h file. (i have updated my question to reflect that).
    – Chris Hill
    Commented Feb 17, 2012 at 20:19

2 Answers 2

49

You may need to surround the function prototype with:

#if defined __cplusplus
extern "C" {
#endif

void swrve_currency_given (...whatever goes here...);

#if defined __cplusplus
};
#endif

That tells the compiler that it's a C function and not a C++ function.

3
  • Looks like it worked, but boy that's a lot of boiler plate to add! Thanks!
    – Chris Hill
    Commented Feb 17, 2012 at 20:24
  • I've added a variant using the extern "C" syntax variant without block scope, which I find somewhat cleaner as you only have to do the boilerplate stuff once. It was a bit too big for a comment, but the edit should hopefully be approved soon.
    – pmdj
    Commented Feb 19, 2012 at 12:21
  • To clarify the answer for posterity: you add this code to the .h file for the c code.
    – Winston Du
    Commented Aug 27, 2020 at 6:03
10

If you are using c function in c++ file. you should use extern "c"{}. In .h file

#ifdef __cplusplus
extern "C" {
#endif

swrve_currency_given(parameter1, parameter2, parameter3);// a c function


#ifdef __cplusplus
}
#endif  

extern "C" is meant to be recognized by a C++ compiler and to notify the compiler that the noted function is (or to be) compiled in C style.

If you're linking to a library that was compiled as C code. use

extern "C" {
  #include "c_only_header.h"
}

Take a look at When to use extern "C" in C++?

Not the answer you're looking for? Browse other questions tagged or ask your own question.