Python C-extension submodule Error: no module named "x"

Python C-extension submodule Error: no module named "x"

我在将 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]+ [=10=]
  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] = '[=10=]';
  } 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

我不太确定我错过了什么。我还检查了以下 link: How to build a Python C Extension so I can import it from a module 但在这一点上它并没有真正帮助我。

我在没有任何源代码修改的情况下让它工作。

  1. 你的目录"mkdir"必须命名为"mpIPC",也就是模块名。你会希望你的目录结构看起来像底部

  2. do not 尝试从您的源目录中测试它,即不要从 project 中的任何地方进行测试,因为这将尝试导入,根据 Python 的模块结构,从目录 "mpIPC"(您将在 1 中创建))(此提示归功于 this comment in the post you mentioned。相反,从任何地方尝试例如,在您的主目录中。也就是说,假设您首先 运行 python setup.py install :)

目录树:

foobar
    ├── mpIPC
    │   ├── __init__.py
    │   ├── os.py
    │   └── prctl3_0.c
    └── setup.py