I am testing of running a Python thread in a c program with a simple example like the below
# demo.py
import time
for i in range(1, 101):
print(i)
time.sleep(0.1)
// demo.c
#include <Python.h>
#include <pthread.h>
#include <stdio.h>
void *run_python_script(void *arg) {
Py_Initialize();
if (!Py_IsInitialized()) {
fprintf(stderr, "Python initialization failed\n");
return NULL;
}
FILE *fp = fopen("demo.py", "r");
if (fp == NULL) {
fprintf(stderr, "Failed to open demo.py\n");
Py_Finalize();
return NULL;
}
PyRun_SimpleFile(fp, "demo.py");
fclose(fp);
Py_Finalize();
return NULL;
}
int main() {
pthread_t python_thread;
if (pthread_create(&python_thread, NULL, run_python_script, NULL) != 0) {
fprintf(stderr, "Failed to create thread\n");
return 1;
}
pthread_join(python_thread, NULL);
printf("Python thread has finished. Exiting program.\n");
return 0;
}
Then I build the above code with the following command
gcc demo.c -o demo -lpthread -I$(python3-config --includes) $(python3-config --ldflags) $(python3-config --cflags)
Then I get the following error:
/usr/bin/ld: /tmp/ccsHQpZ3.o: in function `run_python_script':
demo.c:(.text.run_python_script+0x7): undefined reference to `Py_Initialize'
/usr/bin/ld: demo.c:(.text.run_python_script+0xd): undefined reference to `Py_IsInitialized'
/usr/bin/ld: demo.c:(.text.run_python_script+0x41): undefined reference to `PyRun_SimpleFileExFlags'
/usr/bin/ld: demo.c:(.text.run_python_script+0x50): undefined reference to `Py_Finalize'
/usr/bin/ld: demo.c:(.text.run_python_script+0xab): undefined reference to `Py_Finalize'
collect2: error: ld returned 1 exit status
The python library do exists,
python3-config --ldflags
-L/home/henry/anaconda3/lib/python3.9/config-3.9-x86_64-linux-gnu -L/home/henry/anaconda3/lib -lcrypt -lpthread -ldl -lutil -lm -lm
ls -1 ~/anaconda3/lib | grep python
libpython3.9.so
libpython3.9.so.1.0
libpython3.so
python3.9
I have no idea about is link error.
You need to pass --embed
to python3-config
because you are embedding a Python interpreter in your program. Observe the difference:
$ python3-config --ldflags
-L/usr/lib/python3.10/config-3.10-x86_64-linux-gnu
-L/usr/lib/x86_64-linux-gnu -lcrypt -ldl -lm -lm
$ python3-config --embed --ldflags
-L/usr/lib/python3.10/config-3.10-x86_64-linux-gnu
-L/usr/lib/x86_64-linux-gnu -lpython3.10 -lcrypt -ldl -lm -lm