在windows 上pyd文件其实本质上就是一个dll文件,本文记录一下如果通过def文件导出额外的stdcall文件。
先看完整的代码setup.py
from setuptools import setup, Extension
mod_name = "sample"
def_ = '''LIBRARY
EXPORTS
test
'''
with open(mod_name + ".def","w") as f:
f.write(def_)
setup(name=mod_name, ext_modules=[
Extension(
mod_name,
["{}.cpp".format(mod_name)],
include_dirs = ['..'],
extra_link_args=['/DEF:"{}.def"'.format(mod_name)],
)
]
)
sample.cpp
#include "Python.h"
int __stdcall test(){
printf(" __stdcall test\n");
return 1;
}
static PyObject *py_test(PyObject *self, PyObject *args) {
printf(" py test\n");
return Py_BuildValue("i", 233);
}
static PyMethodDef SampleMethods[] = {
{"test", py_test, METH_VARARGS, "Greatest common divisor"},
{ NULL, NULL, 0, NULL}
};
static struct PyModuleDef samplemodule = {
PyModuleDef_HEAD_INIT,
"sample", /* name of module */
"A sample module", /* Doc string (may be NULL) */
-1, /* Size of per-interpreter state or -1 */
SampleMethods /* Method table */
};
PyMODINIT_FUNC
PyInit_sample(void) {
return PyModule_Create(&samplemodule);
}
打包命令
python.exe setup.py install
实际执行的批处理命令
C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\BIN\cl.exe /c /nologo /Ox /MD /W3 /GS- /DNDEBUG -I.. -IE:\Python34\include -IE:\Python34\include /Tpsample.cpp /Fobuild\temp.win32-3.4\Release\sample.obj
C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\BIN\link.exe /DLL /nologo /INCREMENTAL:NO /LIBPATH:E:\Python34\libs /LIBPATH:E:\Python34\PCbuild /EXPORT:PyInit_sample build\temp.win32-3.4\Release\sample.obj /OUT:build\lib.win32-3.4\sample.pyd /IMPLIB:build\temp.win32-3.4\Release\sample.lib /MANIFESTFILE:build\temp.win32-3.4\Release\sample.pyd.manifest /DEF:"sample.def"
test_sample.py
import sample
print("返回",sample.test())
import ctypes
sp = ctypes.WinDLL(sample.__file__)
print("返回",sp.test())
输出
py test
返回 233
__stdcall test
返回 1