zfgo
zfgo

Reputation: 355

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

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.

Upvotes: 6

Views: 1709

Answers (4)

Mazen Al Khatib
Mazen Al Khatib

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

Oshitha Wimalasuriya
Oshitha Wimalasuriya

Reputation: 451

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

Please refer this link

Upvotes: 0

JustSid
JustSid

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

Bernd
Bernd

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

Related Questions