Reputation: 355
I am creating a sample static library to be used in my iOS app, however, when calling the static library's methods, I ran into a linker error:
Undefined symbols for architecture arm64:
"_doMath", referenced from:
_doMathInterface in libTestMain.a(Test.o)
(maybe you meant: _doMathInterface)
ld: symbol(s) not found for architecture arm64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
Here is the static library's structure:
I have a header file Test.h:
#import <Foundation/Foundation.h>
@interface Test : NSObject
int doMathInterface(int a, int b);
@end
and its implementation Test.m :
#import "Test.h"
#include "PaymentAPI.h"
@implementation Test
int doMathInterface(int a, int b){
return doMath(a, b);
}
@end
and in PaymentAPI.h:
#ifndef PaymentAPI_h
#define PaymentAPI_h
int doMath(int a, int b);
#endif /* PaymentAPI_h */
Finally in PaymentAPI.cpp:
#include <stdio.h>
#include "PaymentAPI.h"
int doMath(int a, int b){
return a + b;
}
As you can see it's a very simple static library but I couldn't figure out why this linker error is happening, I have added the static library in the "Link Binaries with Libraries" in Build Phases in the app.
Here is a screenshot of the app's files:
and search paths configuration in build settings is also correct, I believe:
Here is a screenshot of some build settings for the static library project
Thanks a lot.
Upvotes: 6
Views: 1709
Reputation: 308
you better use djinni if you want to do static libraries with C++ since it will handle the bridging functionalities including functions names and symbols.
Upvotes: 0
Reputation: 451
When you are calling C++ function through Objective-C you have to create wrapper class(.mm file).
Upvotes: 0
Reputation: 25318
The problem is that your doMath
function gets compiled as C++ code, which means that the function name gets mangled by the C++ compiler. Your Test.m
file however gets consumed by the (Objective-)C compiler and C doesn't use name mangling.
This means that the linker will end up looking for the wrong symbol. You can fix this by having the C++ compiler emit an unmangled function name. To do so, you'll have to use extern "C"
in PaymenAPI.h like so:
#ifndef PaymentAPI_h
#define PaymentAPI_h
#ifdef __cplusplus
extern "C" {
#endif
int doMath(int a, int b);
#ifdef __cplusplus
}
#endif
#endif /* PaymentAPI_h */
For a complete explanation you can take a look at this SO question and the accepted answer: Combining C++ and C - how does #ifdef __cplusplus work?
Upvotes: 2
Reputation: 2211
The linker sees the symbol name "_doMath" not "doMath" - so I think you do the interop not correctly.
I found this: mixing-objective-c-and-c And here is a good article which explains how to do interop between C++ and ObjectiveC / ObjeciveC++:
https://www.drdobbs.com/cpp/interoperating-between-c-and-objective-c/240165502
=> try to rename your .m file to .mm
Upvotes: -1