Undefined symbols for architecture arm64 after linking a static library in iOS app
Asked Answered
L

4

6

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:

enter image description here

and search paths configuration in build settings is also correct, I believe:

enter image description here

Here is a screenshot of some build settings for the static library project

Build Phases: enter image description here

Architecture: enter image description here

Thanks a lot.

Ladew answered 9/7, 2020 at 18:54 Comment(0)
K
2

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?

Kilmarx answered 15/7, 2020 at 13:51 Comment(0)
C
0

When you are calling C++ function through Objective-C you have to create wrapper class(.mm file).

Please refer this link

Corcoran answered 16/7, 2020 at 8:30 Comment(0)
M
0

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.

Marquand answered 18/7, 2020 at 16:26 Comment(0)
D
-1

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

Dolomite answered 15/7, 2020 at 13:19 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.