spammoudle.c 文件
#include <Python.h>
static PyObject *SpamError;
static PyObject * spam_system(PyObject *self, PyObject *args) {
const char *command;
int sts;
if (!PyArg_ParseTuple(args, "s", &command))
return NULL;
sts = system(command);
if (sts < 0) {
PyErr_SetString(SpamError, "System command failed");
return NULL;
}
return PyLong_FromLong(sts);
}
static PyMethodDef SpamMethods[] = {
{"system", spam_system, METH_VARARGS, "Execute a shell command."},
{NULL, NULL, 0, NULL} /* Sentinel */
};
static struct PyModuleDef spammodule = {
PyModuleDef_HEAD_INIT,
"spam", /* name of module */
NULL, /* module documentation, may be NULL */
-1, /* size of per-interpreter state of the module,
or -1 if the module keeps state in global variables. */
SpamMethods
};
PyMODINIT_FUNC PyInit_spam(void) { // non-static
PyObject *m;
m = PyModule_Create(&spammodule);
if (m == NULL)
return NULL;
SpamError = PyErr_NewException("spam.error", NULL, NULL);
Py_INCREF(SpamError);
PyModule_AddObject(m, "error", SpamError);
return m;
}
int main(int argc, char *argv[]) {
wchar_t *program = Py_DecodeLocale(argv[0], NULL);
if (program == NULL) {
fprintf(stderr, "Fatal error: cannot decode argv[0]\n");
exit(1);
}
/* Add a built-in module, before Py_Initialize */
PyImport_AppendInittab("spam", PyInit_spam);
/* Pass argv[0] to the Python interpreter */
Py_SetProgramName(program);
/* Initialize the Python interpreter. Required. */
Py_Initialize();
/* Optionally import the module; alternatively,
import can be deferred until the embedded script
imports it. */
PyImport_ImportModule("spam");
PyMem_RawFree(program);
return 0;
}
setup.py 文件
from distutils.core import setup, Extension
module = Extension('spam', sources = ['spammoudle.c'])
setup (
name = 'PackageName',
version = '1.0',
description = 'This is a demo package',
ext_modules = [module],
)
shell 安装:
python setup.py build # 安装
> running build
> running build_ext
> building 'spam' extension
> /usr/bin/clang -fno-strict-aliasing -Wsign-compare -fno-common -dynamic -DNDEBUG -g -fwrapv -O3 -Wall -Wstrict-prototypes -arch i386 -arch x86_64 -g -I/Library/Frameworks/Python.framework/Versions/3.6/include/python3.6m -c spammoudle.c -o build/temp.macosx-10.6-intel-3.6/spammoudle.o
> creating build/lib.macosx-10.6-intel-3.6
> /usr/bin/clang -bundle -undefined dynamic_lookup -arch i386 -arch x86_64 -g build/temp.macosx-10.6-intel-3.6/spammoudle.o -o build/lib.macosx-10.6-intel-3.6/spam.cpython-36m-darwin.so
> ld: warning: The i386 architecture is deprecated for macOS (remove from the Xcode build setting: ARCHS)
> ld: warning: ignoring file /Library/Developer/CommandLineTools/SDKs/MacOSX10.14.sdk/usr/lib/libSystem.tbd, missing required architecture i386 in file /Library/Developer/CommandLineTools/SDKs/MacOSX10.14.sdk/usr/lib/libSystem.tbd
导入使用
进入/build/lib.macosx-10.6-intel-3.6/ 找到 spam.cpython-36m-darwin.so,同级目录下import spam 导入到py文件中使用