Search code examples
pythonlinkershared-librariesctypesextern

How to use python ctypes to define an undefined symbol


I would like to use a shared library (with python ctypes) which expects that some symbols are defined in the program that uses this shared library.

In the following example, var is defined in test.c, while nm libadd.so shows that var is undefined;

/* libadd.c */
#include <stdio.h>

extern int var;

int add(int a, int b) {
    return (a + b + var);
}
gcc -c -Wall -Werror -fpic libadd.c
gcc -shared -o libadd.so libadd.o
/* test.c */
#include <stdio.h>
#include "libadd.h"

int var = 1;

int main(void) {
    printf("%d", add(1,2));
    return 0;
}
gcc -L/path/to/libadd -Wall -o test test.c -ladd

Similarly, how to do this with python ctypes;

# test.py
from ctypes import *

#what to do to define var?

sharedlib = CDLL("sharedlib/libadd.so", mode = RTLD_GLOBAL)
print( sharedlib.add(1,2) )
OSError: sharedlib/libadd.so: undefined symbol: var

Solution

  • One possibility is to create a seperate shared library to define var and load this before libadd.so.

    /* resolve.c */
    int var = 1;
    
    gcc -c -Wall -Werror -fpic resolve.c
    gcc -shared -o resolve.so resolve.o
    
    from ctypes import *
    
    sharedlib = CDLL("sharedlib/resolve.so", mode = RTLD_GLOBAL)
    sharedlib = CDLL("sharedlib/libadd.so", mode = RTLD_GLOBAL)