Python Forum
C-API - Cannot create module
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
C-API - Cannot create module
#1
I have another problem with my project (convert to Python 3 - Euler Math Toolbox). The following code should create a module. But it does not work. The interpreted line "import eumat" returns "module eumat not found".

It is probably my last trouble with this project (fingers crossed).

Thanks for advice!

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

const char* pystart = "import eumat\nprint(eumat.test())";

static PyObject* ftest (PyObject* self, PyObject* args)
{
	return PyLong_FromLong(1000);
}

static PyMethodDef EmbMethods[] = {
	{"test", ftest, METH_NOARGS,
	 "Test Function"},
	{NULL, NULL, 0, NULL}
};

int main()
{
	printf("Test Programm for Python 3.8\n");

	Py_Initialize();

	static struct PyModuleDef moduledef = {
		PyModuleDef_HEAD_INIT,
		"eumat",
		"EMT Module",
		-1,
		EmbMethods,
		NULL,
		NULL,
		NULL,
		NULL,
	};

	PyObject* eumat = PyModule_Create(&moduledef);
	if (!eumat)
	{
		printf("Could not create eumat module in Python.");
		return 0;
	}

	PyObject* pModule = PyImport_AddModule("__main__"); //create main module
	if (!pModule)
	{
		printf("Could not create main module in Python.");
		return 0;
	}

	if (PyRun_SimpleString(pystart) == -1)
	{
		printf("Could not run pystart.");
		return 0;
	}

	return 1;
}
Reply
#2
The module is not found probably because the directory containing the new shared library eumat.so (or perhaps eumatmodule.so) is not on the python module path. The solution is to add this directory to sys.path.
Reply
#3
As far as I know, the method PyModule_Create() does not create a file. So I do not know what you mean. Sorry.

I have found a partial solution. Importing the module in C was not necessary in Python 2, but now it is. After doing so, the module is found. However, the embedded function is not.

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

const char* pystart = "print('Start')\nimport eumat\nprint(eumat.test())";

static PyObject* ftest (PyObject* self, PyObject* args)
{
	return PyLong_FromLong(1000);
}

static PyMethodDef EmbMethods[] = {
	{"test", ftest, METH_NOARGS,
	 "Test Function"},
	{NULL, NULL, 0, NULL}
};

int main()
{
	printf("Test Programm for Python 3.8\n");

	Py_Initialize();

	static struct PyModuleDef moduledef = {
		PyModuleDef_HEAD_INIT,
		"eumat",
		"EMT Module",
		-1,
		EmbMethods,
		NULL,
		NULL,
		NULL,
		NULL,
	};

	PyObject* eumat = PyModule_Create(&moduledef);
	if (!eumat)
	{
		printf("Could not create eumat module in Python.");
		return 0;
	}

	PyObject* pModule = PyImport_AddModule("__main__"); //create main module
	if (!pModule)
	{
		printf("Could not a module in Python.");
		return 0;
	}

	pModule = PyImport_AddModule("eumat"); //create main module
	if (!pModule)
	{
		printf("Could not a module in Python.");
		return 0;
	}

	if (PyRun_SimpleString(pystart) == -1)
	{
		printf("Could not run pystart.");
		return 0;
	}

	return 1;
}
Reply
#4
mga010 Wrote:As far as I know, the method PyModule_Create() does not create a file. So I do not know what you mean. Sorry.
Sorry, I think you're right. Then you can insert the module in sys.modules, you can do it like so
sys = PyImport_ImportModule("sys");
sys_modules = PyObject_GetAttrString(sys, "modules");
PyDict_SetItemString(sys_modules, "eumat", eumat);
Then you can normally import eumat because python will find it in sys.modules.
Reply
#5
Thanks, I now found an easy method which works:

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

const char* pystart = 
"print('Start')\n\
import eumat\n\
print(dir(eumat))\n\
print(eumat.test())";

static PyObject* ftest (PyObject* self, PyObject* args)
{
	return PyLong_FromLong(1000);
}

static PyMethodDef EmbMethods[] = {
	{
		"test", (PyCFunction)ftest, METH_NOARGS,"Test Function"
	},
	{NULL, NULL, 0, NULL}
};

int main()
{
	printf("Test Programm for Python 3.8\n");

	Py_Initialize();

	static struct PyModuleDef moduledef = {
		PyModuleDef_HEAD_INIT,
		"eumat",
		PyDoc_STR("EMT Module"),
		-1,
		EmbMethods
	};


	PyObject* eumat = PyImport_AddModule("eumat"); //create main module
	if (!eumat)
	{
		printf("Could not add the module eumat in Python.");
		return 0;
	}

	PyModule_AddFunctions(eumat, EmbMethods);

	if (PyRun_SimpleString(pystart) == -1)
	{
		printf("Could not run pystart.");
		return 0;
	}

	return 1;
}
Reply
#6
If you've found a method that works, that's perfect. This API evolves with every version of python and I don't use it very often, so I'm probably a bit rusty for this.
Reply
#7
(Jun-24-2020, 10:50 AM)Gribouillis Wrote: If you've found a method that works, that's perfect. This API evolves with every version of python and I don't use it very often, so I'm probably a bit rusty for this.

"evolve" sounds nicer than "change", indeed. Backward compatibility, however, is a value in itself.
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  problem in using pyqrcode module to create QRcode akbarza 9 1,987 Aug-23-2023, 04:17 PM
Last Post: snippsat
  how to create a module to solve matrix pappykens 3 2,166 Apr-30-2020, 04:59 PM
Last Post: deanhystad

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020