Reputation: 780
I am constantly seeing
context.c:55: warning: mpd_setminalloc: ignoring request to set MPD_MINALLOC a second time
after every call to the below function in runtime that calls a python function in c++
This function uses Python.h
as explained in https://docs.python.org/2/extending/extending.html
void process_string(string text)
{
//cout<<text<<endl;
PyObject *pName, *pModule, *pDict, *pFunc;
PyObject *pArgs, *pValue;
Py_Initialize();
PyRun_SimpleString("import sys");
PyRun_SimpleString("import os");
PyRun_SimpleString("sys.path.append( os.path.dirname(os.getcwd()) )");
pName = PyUnicode_FromString("python_files.strings");
pModule = PyImport_Import(pName);
Py_DECREF(pName);
if (pModule != nullptr) {
pFunc = PyObject_GetAttrString(pModule, "process_string");
if (pFunc && PyCallable_Check(pFunc)) {
pArgs = PyTuple_New(1);
pValue = PyUnicode_FromString(text.c_str());
cout<<_PyUnicode_AsString(pValue)<<endl;
if (!pValue) {
Py_DECREF(pArgs);
Py_DECREF(pModule);
fprintf(stderr, "Cannot convert argument\n");
}
PyTuple_SetItem(pArgs, 0, pValue);
pValue = PyObject_CallObject(pFunc, pArgs);
Py_DECREF(pArgs);
if (pValue != NULL)
{
//cout<<_PyUnicode_AsString(pValue)<<endl;
Py_DECREF(pValue);
} else {
Py_DECREF(pFunc);
Py_DECREF(pModule);
PyErr_Print();
fprintf(stderr, "Call failed\n");
}
} else {
if (PyErr_Occurred())
PyErr_Print();
fprintf(stderr, "Cannot find function \"%s\"\n", "process_string");
}
Py_XDECREF(pFunc);
Py_DECREF(pModule);
} else {
PyErr_Print();
fprintf(stderr, "Failed to load \"%s\"\n", "python_files.strings");
}
Py_Finalize();
}
The problem is in the c++ side of the code as even if I change the python function to simply return the input, I see the warning on the console.
The string.py file(a example) :
import os
import sys
import warnings
def process_string(text):
if not sys.warnoptions:
warnings.simplefilter("ignore")
return text
I tried disabling warning print on the python side with no advantage.
Upvotes: 5
Views: 3261
Reputation: 17008
I cannot reproduce the behaviour you describe but this is very likely due to the fact that you call Py_Initialize
several times.
Each time after the first one, the decimal
module is initialized and calls mpd_setminalloc with minalloc_is_set == 1
, hence the warning message.
void
mpd_setminalloc(mpd_ssize_t n)
{
static int minalloc_is_set = 0;
if (minalloc_is_set) {
mpd_err_warn("mpd_setminalloc: ignoring request to set "
"MPD_MINALLOC a second time\n");
return;
}
if (n < MPD_MINALLOC_MIN || n > MPD_MINALLOC_MAX) {
mpd_err_fatal("illegal value for MPD_MINALLOC"); /* GCOV_NOT_REACHED */
}
MPD_MINALLOC = n;
minalloc_is_set = 1;
}
You should have the initialization of the Python interpreter in a separate function, and call it once only. For example, if you want to put it in main
:
int
main()
{
int i;
Py_Initialize();
for( i=0; i < 5; i++)
process_string("A nice string");
process_string("Another nice string");
Py_Finalize();
return 0;
}
Note you could also put the imports there, as the Python interpreter will remain alive until your program finishes.
For reference the compiling command I use is:
g++ -c -I/usr/include/python3.6m -Wno-unused-result -Wsign-compare -march=x86-64 -mtune=generic -O2 -pipe -fstack-protector-strong -fno-plt -DNDEBUG -g -fwrapv -O3 -Wall <yourprogram.cpp> -lpython3.6m
And the linking command is:
g++ -g -L/usr/lib -lpython3.6m -lpthread -ldl -lutil -lm -Xlinker -export-dynamic -o <yourexecutable> <yourobjectfile.o>
Upvotes: 5