1

I'm trying some basic experiments with cython (with the ultimate goal being to make a library that I can use in other languages), following these docs. Trying to compile a basic hello world example, however, the compiler can't see my cython-defined function.

The relevant code:

hello.pyx:

cdef public api char* say_hi():
    return "hello from python!"

which I then compile into c with cython hello.pyx

sayhi.c:

#include <Python.h>
#include "hello.h"

int main() {
  Py_Initialize();
  char *hi = say_hi();
  printf("%s\n", hi);
  Py_Finalize();
}

which I then attempt to compile into an executable with

gcc `python2-config --cflags --ldflags` -o compiledhi sayhi.c

which is just what I swiped from this earlier SO answer.

But compilation fails with the following error:

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

If it matters, I'm running this all from within a pipenv shell using python 3.7, on a mac with the current version of xcode installed...

Since I'm using python 3, and just in case it makes a difference, I also tried

gcc `python3-config --cflags --ldflags` -o compiledhi sayhi.c

just as a guess, but no dice.

The cython docs linked above describe an api mode as an alternative way to do this, which I also tried, by replacing the c code above with:

#include <Python.h>
#include "hello_api.h"

int main() {
  Py_Initialize();
  import_hello();
  char *hi = say_hi();
  printf("%s\n", hi);
  Py_Finalize();
}

this compiles, but when I run it, it segfaults.

Help? I think I'm following the docs correctly, though I don't actually know C...

Paul Gowder
  • 2,409
  • 1
  • 21
  • 36
  • not quite sure I understanding @Keatinge --- do you mean, like, two separate lines in the c code? `char *hi; hi = say_hi();` ? – Paul Gowder May 19 '19 at 23:28
  • As you are using Python3 you should not be using `import_hello` but `PyInit_hello`. See also https://stackoverflow.com/q/55647555/5769463 how it should be done in Python>3.5 with current versions of Cython. – ead May 20 '19 at 05:15
  • 1
    Also see in the question linked above, how the gcc is called: you have to pass both `sayhi.c` and `hello_api.c` to gcc. – ead May 20 '19 at 05:16
  • Possible duplicate of [What is an undefined reference/unresolved external symbol error and how do I fix it?](https://stackoverflow.com/questions/12573816/what-is-an-undefined-reference-unresolved-external-symbol-error-and-how-do-i-fix) – ead May 20 '19 at 05:19
  • Probably the most interesting answer in the dup-target is https://stackoverflow.com/a/12574400/5769463 – ead May 20 '19 at 05:21
  • I think the problem is that you haven't compiled hello.c, so it's struggling to find the definition of the function `say_hi` (I'm therefore not sure the duplicate is hugely useful) – DavidW May 20 '19 at 08:42
  • aaah! adding hello.c to the compilation got it working. That massive pile of noise in the other question isn't terribly helpful but if someone wants to post an answer along the lines of "add the other c file to the compilation command, importing the header isn't enough information for gcc to know to do it," I'd happily accept it and get someone the rep. – Paul Gowder May 20 '19 at 17:29

0 Answers0