2

C++ dylib exposes as follows

__attribute__((visibility("default"))) int addNumber(int number) {
    return 0;
}

in my Swift project, I set the Import Paths dir to the dir containing my module.map file:

module MyLib {
    header "myLib.h"
    export *
}

I manually add myLib.h to my project:

#ifndef mylib_h
#define mylib_h

int addNumber(int number);

#endif 

My main.swift does the following:

import Foundation
import MyLib

print("Hello, World!")
var result = addNumber(3)

When I compile the swift project, I can see that it links against my dylib (-lMyLib), but I get the following error:

Undefined symbols for architecture x86_64: "_addNumber", referenced from: _main in main.o ld: symbol(s) not found for architecture x86_64 clang: error: linker command failed with exit code 1 (use -v to see invocation)

So although it's linking correctly, it can't find the symbols. I've verified both with nm (0000000000000d00 (__TEXT,__text) external addNumber) and Hopper that this function does exist in the dylib.

Shai
  • 25,159
  • 9
  • 44
  • 67
  • Did you mark the function with `extern "C"` for C linkage? – Martin R Mar 21 '18 at 12:26
  • @MartinR that solved the compile issue. Thanks! Now there's a runtime issue :) will update – Shai Mar 21 '18 at 12:35
  • @MartinR yep, once adding a "copy" phase of the dylib post-build, everything seems to be working. Feel free to post an answer so I can accept it. Thanks! – Shai Mar 21 '18 at 12:36

1 Answers1

2

In the C++ library, your function must be marked with extern "C" for C linkage:

extern "C" __attribute__((visibility("default"))) int addNumber(int number) {
    return 0;
}

so that the compiler does not mangle the exported name. Swift can only call C functions, not C++ functions.

See also What is the effect of extern "C" in C++?.

Martin R
  • 529,903
  • 94
  • 1,240
  • 1,382