1

i am trying to integrate my own small cpp project into a big objective-c project. I have compiled my own project into a .dylib file and added into the big project, and .h file is included. But in order to follow the legacy i have to call my function from a .m file in the big project.

i know that .m file can not call cpp functions so what i have tried is to include my cpp .h file in another .mm file, then in my .m file i include the header file to the .mm file. here is what i did:

A.mm (i created this file together with the header)

#import "A.h"
#include "mycppfunc.h"
int ParseFile(char * filename)
{
    ....(using cpp functions)
    return 0;
}

A.h

int ParseFile(char* filename);

B.mm (originally in the big project)

#import "B.h"
#import "A.h"
.... (original codes in B.mm)

B.h

#import "C.h"
....

C.m (originally in the big project, i have to call my own functions from here due to legacy)

#import "C.h"
#import "B.h"
....
- (IBAction) call_my_proj: (id) sender
{
    ....
    ParseFile("myfile.txt");
}

C.h

.... (this file is un-changed)

When i compile, i got this error:

Implicit declaration of function 'ParseFile' is invalid in C99

Can anyone help me explain where it went wrong? Can it be due to the circular reference to different header file (but i can not change it since it affects other peoples code). how can i get rid of this error? any help is highly appreciated! thanks.

  • 3
    Are you including `A.h` anywhere (e.g. from C.h or C.m)? That's the only place that `ParseFile` is defined. – Nathan S. Jan 13 '14 at 05:17

3 Answers3

1

You need to #include "A.h" in C.m. You are calling ParseFile() in C.m.

user1118321
  • 25,567
  • 4
  • 55
  • 86
  • thanks. but once i included A.h in C.m i got the linker error – user3188926 Jan 13 '14 at 06:50
  • Undefined symbols for architecture i386: "_ParseFile", referenced from: -[...this is where i call the ParseFile function] in C.o ld: symbol(s) not found for architecture i386 clang: error: linker command failed with exit code 1 (use -v to see invocation) – user3188926 Jan 13 '14 at 06:51
0

Rename extension of all your .m files to .mm. This way you can directly call cpp functions in your objective-C classes without any wrappers.

CodenameLambda1
  • 1,299
  • 7
  • 17
  • thanks Lambda1 but i can not change the extension as it affects the code written by other people. what can i do instead? – user3188926 Jan 13 '14 at 06:49
0

First, you need to include A.h from C.h or C.m.

But, because the functions defined in A.mm are being compiled with a (Obj)C++ compiler, you might need to make them callable from C. You do this using C linkage. Then ParseFile() should be callable from the C.m file. For instance, in the header file:

extern "C"
{
   int ParseFile(const char *);
}
Community
  • 1
  • 1
Nathan S.
  • 5,244
  • 3
  • 45
  • 55
  • Thanks Nathan, this seems to make some progress. i added #ifdef __cplusplus extern "C" { #endif int ParseFile(char * filename); #ifdef __cplusplus } #endif – user3188926 Jan 13 '14 at 07:50
  • Thanks Nathan, this seems to make some progress. i added #ifdef __cplusplus extern "C" { #endif int ParseFile(char * filename); #ifdef __cplusplus } #endif and when i compile i don't get the same error anymore. however, it seems to mess up the namespace in a cpp file (D.cpp) which is called by A.mm (D.h is included in A.mm). i got error "redefinition of '' as a different kind of symbol", and some class names become "undeclared"---i got "use of undeclared identifier xxxx " error. Do you have any idea why it became so? – user3188926 Jan 13 '14 at 08:00
  • I would first look at the namespaces being used in D.cpp/D.h to see if there is a naming conflict with ParseFile or some other function. – Nathan S. Jan 13 '14 at 16:36