[Python] PyImportMoule in Python.h crashes every time

Discussão em 'Python' iniciado por Stack, Abril 19, 2025.

  1. Stack

    Stack Membro Participativo

    I'm creating a wallet application in C. It has a lot of features, but the one that gives me problems is this one:

    case 4:
    printf("\nWait a second while we're updating your currency...\n");
    currency = PyUnicode_AsUTF8(run_python());
    printf("Done\n");
    break;


    This function updates the currency (the symbol of the currency: EUR, USD, ...), it calls another function which is this one:

    PyObject* run_python() {
    Py_Initialize();
    PyRun_SimpleString("import sys\nsys.stderr = sys.stdout\n");
    PyObject* pModule = Py_None;
    pModule = PyImport_ImportModule("geo");
    PyObject* get_currency = PyObject_GetAttrString(pModule, "get_currency");
    PyObject* currency1= PyObject_CallObject(get_currency, NULL);
    if (currency1 == NULL) {
    printf("Something went wrong, tou must be connected to the Internet, try again! :(");
    Py_DecRef(get_currency);
    Py_DecRef(currency1);
    Py_DecRef(pModule);
    Py_Finalize();
    } else {
    Py_DecRef(get_currency);
    Py_DecRef(currency1);
    Py_DecRef(pModule);
    Py_Finalize();
    return currency1;
    }
    }


    This piece of code imports an extern Python module, runs the get_currency() function and gives back the result.

    The function get_currency() is written like this:

    def get_currency():
    try:
    print("Getting the currency, please wait...\n")
    response = requests.get(f'https://ipapi.co/{getIP()}/json/').json()
    curr = response.get("currency")
    return curr
    except:
    print("Error, this error could be an Internet connection Error or an API error, the default currency will be applied or wait some time and try again.\n")
    return "EUR"


    If you notice, in the URL it calls another function getIP(), which is:

    # Gets host's IP address, having default 'returnType' as 'plain', which can be changed accordingly.
    def getIP(returnType = 'plain'):
    try:
    if isinstance(returnType,str):
    returnType = returnType.lower()
    if returnType in ipValidTypes:
    if returnType == 'plain':
    return getPlainResponse(ipLookup[returnType])
    else:
    return getJsonResponse(ipLookup[returnType],'')
    else:
    raise ValueError('\'returnType\' does not belong in valid types: ' + str(ipValidTypes))
    else:
    raise TypeError('\'returnType\' must be of type \'str\'(' + type(returnType).__name__ + ' was given).')
    except:
    return -1


    So in practice, my C function to update the currency calls the Run_Python() function, which runs the get_currency() function. It takes the host's IP with the getIP() function and with an API call, it takes the currency of the state where the host is. Then the get_currency() returns the currency to the main program.

    Everything works fine, I call the update_currency function and works fine. But if I call it a second time the program crashes, I tried to debug and I found that the problem is in the PyImportModule function: pModule = PyImport_ImportModule("geo");

    I tried to call the function after 10 minutes, but it still gives me the error.

    How can I solve this?

    If you want to reproduce:

    Create a C file with this code:

    #include <stdio.h>
    #include <Python.h>

    PyObject* runPython(){
    Py_Initialize();
    PyObject* pModule = PyImport_ImportModule("example");
    PyObject* add = PyObject_GetAttrString(pModule, "add");
    PyObject* result = PyObject_CallObject(add, NULL);

    //cleaning up
    Py_DecRef(add);
    Py_DecRef(result);
    Py_DecRef(pModule);
    Py_Finalize();

    return result;
    }

    int main(){
    printf("%s", PyUnicode_AsUTF8(runPython()));
    printf("%s", PyUnicode_AsUTF8(runPython()));

    return 0;
    }


    A Python file called example.py, with:

    import requests

    def add():
    response = requests.get(f'https://ipapi.co/8.8.8.8/json/').json()
    curr = response.get("currency")
    return curr


    Then compile with:

    gcc -static -o try try.c -IC:\Python312\include -LC:\Python312\libs -lpython312


    EDIT II:

    Someone suggested me to return a non-PyObject so the updated c file is:

    #include <stdio.h>
    #include <Python.h>


    const char* runPython(){
    Py_Initialize();
    PyObject* pModule = PyImport_ImportModule("example");
    PyObject* add = PyObject_GetAttrString(pModule, "add");
    PyObject* resultPy= PyObject_CallObject(add, NULL);
    //Here I'm assigning the value to a char*
    const char* result = PyUnicode_AsUTF8(resultPy);

    //cleaning up
    Py_DecRef(add);
    Py_DecRef(resultPy);
    Py_DecRef(pModule);
    Py_Finalize();

    return result;
    }

    int main(){
    printf("%s", runPython());
    printf("%s", runPython());

    return 0;
    }


    Then in the python file changes nothing, and you can compile it with the same instruction.

    I tried it, but the first call is fine, instead the second one crashes the program.

    I strat to think that it's not a code problem, because I tried with a simple "add()" function in the python file and everything works fine. I'm thinking that maybe is a network protocol problem, because when I wasn't accessing the Internet everything was working fine. So maybe it's a network problem.

    Continue reading...

Compartilhe esta Página