views:

238

answers:

3

Hi, I'm trying to use the functionality of the example iPhone app AQOfflineRenderTest in my app (this app specifically isn't important, I just thought it worth mentioning). I have a C++ file with method called:

    void DoAQOfflineRender(CFURLRef sourceURL, CFURLRef destinationURL)

I'm trying to call this from my Cocoa Objective-C class. The example app I referenced above does this by declaring the method in the header file like so:

    - (IBAction)doSomethingAction:(id)sender;
    @end
    void DoAQOfflineRender(CFURLRef sourceURL, CFURLRef destinationURL);

In the implementation file I call the doSomethingAction which calls renderAudio and executes the same code:

    DoAQOfflineRender(sourceURL, destinationURL);

When I execute I get the error: _DoAQOfflineRender", referenced from: -[myViewController renderAudio] in myViewController.o symbol(s) not found collect2: ld returned 1 exit status

Am I missing a reference to this C++ class? It doesn't specify one in the example app but it runs.

Please help and thanks!

Joe

+1  A: 

What you're missing is the implementation of DoAQOfflineRender -- did you forget to link in the library where this routine is defined?

fbrereto
A: 

It looks like you're using .m as the extension for you Objective-C source file so the compiler thinks you are referencing a C function. Try changing the extension to .mm.

Amuck
A: 

To call a C++ function from a C or Objective-C file, you must declare it with extern "C" linkage in C++.

#if __cplusplus
extern "C" {
#endif

void DoAQOfflineRender(CFURLRef sourceURL, CFURLRef destinationURL);

#if __cplusplus
}
#endif

The reason for this is that C++ functions’ names are modified by encoding their types, so that functions with the same name but different signatures become different symbols. For example, DoAQOfflineRender(CFURLRef, CFURLRef) becomes __Z17DoAQOfflineRenderPK7__CFURLS1_ without extern "C", but _DoAQOfflineRender with it, which is what the C/Objective-C expects.

Ahruman
Does that mean you can't overload C++ functions and declare them all `extern "C"`?
jtbandes
That's correct. If you want to overload, use the `.mm` trick to turn the Objective-C file using it into an Objective-C++ file.
Brent Royal-Gordon
in the example at: http://developer.apple.com/iphone/library/samplecode/AQOfflineRenderTest/index.html a C++ class is used without the declaration you made above. How do they do it?
Buffernet
jtbandes: you can’t overload C++ functions declared extern "C", no. Joe: if they’re using a C++ class (as opposed to a function), they must logically be using Objective-C++ rather than Objective-C
Ahruman