简体   繁体   中英

SWIG error on python import 'undefined symbol: mysql_query'

I am building a small "proof of concept" library system in python and would like to have the database handled by a c extension (for security and to stop someone from meddling with the code)

I compiled everything and now have my _databaseHandler.so file but sadly python crashes upon import

My C code

#include "library.h"

#include <stdio.h>
#include <stdlib.h>
#include <mysql/mysql.h>



MYSQL connect(){

    MYSQL *con = mysql_init(NULL);
    const char *address = "rarehost.net";
    const char *username = "MySQL-name";
    const char *password = "MySQL-password";
    const char *databaseName = "dbname";
    const unsigned int port = 3306;


    if(con == NULL){
        fprintf(stderr, "%s\n", mysql_error(con));
        exit(1);
    }

    if(mysql_real_connect(con, address, username, password, databaseName, port, NULL, 0) == NULL) {
        fprintf(stderr, "%s\n", mysql_error(con));
    } else{
        return *con;
    }
}

void finish_with_error(MYSQL *con)
{
    fprintf(stderr, "%s\n", mysql_error(con));
    mysql_close(con);
    exit(1);
}

char* getCustomers() {
    MYSQL con = connect();

    if (mysql_query(&con, "SELECT * FROM cars")) {
        finish_with_error(&con);
    }

    MYSQL_RES *result = mysql_store_result(&con);
    int num_fields = mysql_num_fields(result);

    MYSQL_ROW row;

    while((row = mysql_fetch_row(result))) {
        for (int i = 0; i < num_fields; ++i) {
            printf("%s ", row[i] ? row[i] : "NULL");
            /*return row[i] ? row[i] : "NULL";*/
        }

        printf("\n");
    }
    return "hi";
}

And yes I know it just returns hi, this is for testing purposes until I manage to import it into python.

My header file

#ifndef DATABASEHANDLER_LIBRARY_H
#define DATABASEHANDLER_LIBRARY_H

#include <mysql/mysql.h>
#include <stdio.h>
#include <stdlib.h>

char* getCustomers();


#endif //DATABASEHANDLER_LIBRARY_H

My interface file

%module databaseHandler
%{
#include "library.h"
#include <mysql/mysql.h>
%}

char* getCustomers();

And last but not least my makefile


_databaseHandler.so: library.o library_wrap.o
    gcc -shared library.o library_wrap.o -o _databaseHandler.so

library.o:
    gcc -c -fPIC library.c -I/usr/include/mariadb/mysql

library_wrap.o:
    swig -python library.i
    gcc -c -fPIC library_wrap.c -I/usr/include/python3.7

And here is the output that has been giving me nightmares:

Traceback (most recent call last):
  File "/home/user/CLionProjects/databaseHandler/databaseHandler.py", line 14, in swig_import_helper
    return importlib.import_module(mname)
  File "/usr/lib/python3.7/importlib/__init__.py", line 127, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
  File "<frozen importlib._bootstrap>", line 1006, in _gcd_import
  File "<frozen importlib._bootstrap>", line 983, in _find_and_load
  File "<frozen importlib._bootstrap>", line 967, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 670, in _load_unlocked
  File "<frozen importlib._bootstrap>", line 583, in module_from_spec
  File "<frozen importlib._bootstrap_external>", line 1043, in create_module
  File "<frozen importlib._bootstrap>", line 219, in _call_with_frames_removed
ImportError: /home/user/CLionProjects/databaseHandler/_databaseHandler.so: undefined symbol: mysql_query

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "test.py", line 1, in <module>
    import databaseHandler
  File "/home/user/CLionProjects/databaseHandler/databaseHandler.py", line 17, in <module>
    _databaseHandler = swig_import_helper()
  File "/home/user/CLionProjects/databaseHandler/databaseHandler.py", line 16, in swig_import_helper
    return importlib.import_module('_databaseHandler')
  File "/usr/lib/python3.7/importlib/__init__.py", line 127, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
ImportError: /home/user/CLionProjects/databaseHandler/_databaseHandler.so: undefined symbol: mysql_query

(The python program is just the import and a print("hello") function)

It's probably some stupid little mistake but I cannot for the life of me find it. Any help is appreciated.

Since your library uses functions from mysql you'll need to link that library against the appropriate library when linking it. (There are other ways you could arrange for the symbol to be defined at runtime, but this is by far the most sensible option)

So in your Makefile you'll want to add something like this:

_databaseHandler.so: library.o library_wrap.o
    gcc -shared library.o library_wrap.o -o _databaseHandler.so -lmysql -L/path/to/lib

(You'll need to supply the exact libary name and path to link against from the package you used to provide it, there's often a pkgconfig file that can help with this or some documentation if it isn't clear).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM