我在代码中将C扩展名作为子模块时遇到了困难。下面的C扩展编译得很好。当我尝试将其添加到另一个模块时会出现问题。
这是C代码:文件名是prctl3-0.c。我能够为Python2.7和Python 3.0编译它。
#include <Python.h>
#include <stdio.h>
#include <string.h>
#include <sys/prctl.h>
// Now we need to identify which version of Python we are working with.
// For backwards compatibility, we need to be able to be compiled by either
// Python 2.7 or Python3.x.
#if PY_MAJOR_VERSION >=3
#define PY_3CODE // We will use this pre-compile statement to differentiate
// between code for Py2.7 and 3.x
#endif
/* osCall_changeName
Calls prctl() to change the name of the calling thread, process or subprocess
*/
static PyObject* osCall_changeName(PyObject*self, PyObject* args)
{
const char *passedInName; // Name passed in by the system
size_t nameLength; // Calculated by calling strlen() on passedInName
char newName[16]; // In Python newName= passedInName[0:15]+ \0
int nameChangeRes; // stores error code for calling prctl()
PyObject *retName; // Return value; Python None if error occurs
// Check if argument passed in successfully
if(! PyArg_ParseTuple(args, "s", &passedInName)){
printf("Error in arg passing\n");
Py_RETURN_NONE;
}
nameLength = strlen(passedInName);
if( nameLength > 15){ // prctl() automatically truncates, but unsure if new string is null-terminated
strncpy(newName, passedInName, 15);
newName[15] = '\0';
} else {
strcpy(newName, passedInName);
}
//Actual function call
nameChangeRes = prctl(PR_SET_NAME, newName, 0,0,0);
if( nameChangeRes == 0 ) // Success; pass back the changed name value
{
retName = Py_BuildValue("s", newName);
return retName;
}
// Method failed; return None
Py_RETURN_NONE;
}
static PyObject* osCall_getName(PyObject* self) {
char procName[16]; // Buffer to put prctl results into
int nameRetrieveRes; // Result of the name retrieval operation
PyObject *retName; // Python object to return values
nameRetrieveRes = prctl(PR_GET_NAME, procName, 0,0,0);
if ( nameRetrieveRes == 0 ) //
{
retName = Py_BuildValue("s", procName);
return retName;
}
printf("Process name change failed\n");
// Operation failed; return None
Py_RETURN_NONE;
}
//==========================================================
// STEP 2: COMPILE THE PIECES NEEDED FOR EITHER 2.7 OR 3.X
// PYTHON LIBRARIES
//==========================================================
static PyMethodDef proc_OsFunc[] = {
{ "changeName",
(PyCFunction)osCall_changeName,
METH_VARARGS,
"Function to give Python process a new associated string ID"},
{ "getName",
(PyCFunction)osCall_getName,
METH_NOARGS,
"Function to get Python process's current string ID"
},
{NULL, NULL, 0, NULL} //function array terminator
};
#ifdef PY_3CODE
static struct PyModuleDef osCallDefine = {
PyModuleDef_HEAD_INIT,
"prctl3_0",
"A simple library for accessing prctl() on Linux from Python 3.0",
-1,
proc_OsFunc
};
#endif
#ifdef PY_3CODE
// Python 3.0 initialization syntax
PyMODINIT_FUNC PyInit_prctl3_0(void)
{
Py_Initialize();
return PyModule_Create(&osCallDefine);
}
#else
// Python 2.0 initialization syntax
PyMODINIT_FUNC initprctl3_0() {
Py_InitModule3("prctl3_0",proc_OsFunc,
"A simple library for accessing prctl() on Linux from Python 2.0");
}
#endif
我希望将此代码作为更大项目的一部分放在模块名mpIPC
中。我遇到的问题是当我把它放入一个更大的模块,并尝试使用以下代码访问它时,我得到以下内容:
>>> import mpIPC.prctl3_0
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ImportError: No module named prctl3_0
我的setup.py
文件如下:
from setuptools import setup, find_packages, Extension
prctl_module = Extension("mpIPC.prctl3_0",
sources = ["mpIPC/prctl3_0.c"])
setup(name = "mpIPC",
version = '0.0',
description = "Python C module for accessing Linux commands for IPC",
packages = ['mpIPC'],
ext_modules = [prctl_module] )
此模块的文件目录:
project/
+- setup.py
+- mkdir/
-+- __init__.py
-+- prctl3_0.c
-+- os.py # used for other Linux os calls
我不确定我错过了什么。我还检查了以下链接: How to build a Python C Extension so I can import it from a module 但在这一点上它并没有真正帮助我。
答案 0 :(得分:0)
我没有任何源代码修改工作。
您的目录&#34; mkdir&#34; 必须命名为&#34; mpIPC&#34;,这是模块名称。您希望您的目录结构看起来像在底部
尝试从您的源目录中进行测试,即不是来自project
中的任何地方,因为它会尝试导入,根据Python&#39; s模块结构,来自目录&#34; mpIPC&#34; (你将在1中创建))(此提示的信用额转到this comment in the post you mentioned。相反,请在home-dir的任何位置尝试。例如,假设您先运行python setup.py install
:)
目录树:
foobar
├── mpIPC
│ ├── __init__.py
│ ├── os.py
│ └── prctl3_0.c
└── setup.py