-
//my_python.c
-
#include
-
-
int
main
(
int
argc
,
char
*
argv
[])
-
{
-
Py_SetProgramName
(
argv
[
0
]);
-
Py_Initialize
();
-
PyRun_SimpleString
(
"print 'Hello Python!'
\n
"
);
-
Py_Finalize
();
-
return
0
;
-
}
cl my_python.c -IC:\Python27\include C:\Python27\libs\python27.lib
gcc my_python.c -o my_python -I/usr/include/python2.7/ -lpython2.7
Hello Python!
-
def
great_function
(
a
):
-
return
a
+
1
-
int
great_function_from_python
(
int
a
)
{
-
int
res
;
-
// some magic
-
return
res
;
-
}
-
#include
-
-
int
great_function_from_python
(
int
a
)
{
-
int
res
;
-
PyObject
*
pModule
,
*
pFunc
;
-
PyObject
*
pArgs
,
*
pValue
;
-
-
/* import */
-
pModule
=
PyImport_Import
(
PyString_FromString
(
"great_module"
));
-
-
/* great_module.great_function */
-
pFunc
=
PyObject_GetAttrString
(
pModule
,
"great_function"
);
-
-
/* build args */
-
pArgs
=
PyTuple_New
(
1
);
-
PyTuple_SetItem
(
pArgs
,
0
,
PyInt_FromLong
(
a
));
-
-
/* call */
-
pValue
=
PyObject_CallObject
(
pFunc
,
pArgs
);
-
-
res
=
PyInt_AsLong
(
pValue
);
-
return
res
;
-
}
现在我们得到了一个C语言的函数了,可以写一个main测试它
-
#include
-
-
int
great_function_from_python
(
int
a
);
-
-
int
main
(
int
argc
,
char
*
argv
[])
{
-
Py_Initialize
();
-
printf
(
"%d"
,
great_function_from_python
(
2
));
-
Py_Finalize
();
-
}
编译的方式就用本节开头使用的方法。
在Linux/Mac OSX运行此示例之前,可能先需要设置环境变量:
bash:
export PYTHONPATH=.:$PYTHONPATH
csh:
setenv PYTHONPATH .:$PYTHONPATH
-
int great_function(int a) {
-
return a + 1;
-
}
-
>>> from great_module import great_function
-
>>> great_function(2)
-
3
-
#include
-
-
int
great_function
(
int
a
)
{
-
return
a
+
1
;
-
}
-
-
static
PyObject
*
_great_function
(
PyObject
*
self
,
PyObject
*
args
)
-
{
-
int
_a
;
-
int
res
;
-
-
if
(
!
PyArg_ParseTuple
(
args
,
"i"
,
&
_a
))
-
return
NULL
;
-
res
=
great_function
(
_a
);
-
return
PyLong_FromLong
(
res
);
-
}
-
-
static
PyMethodDef
GreateModuleMethods
[]
=
{
-
{
-
"great_function"
,
-
_great_function
,
-
METH_VARARGS
,
-
""
-
},
-
{
NULL
,
NULL
,
0
,
NULL
}
-
};
-
-
PyMODINIT_FUNC
initgreat_module
(
void
)
{
-
(
void
)
Py_InitModule
(
"great_module"
,
GreateModuleMethods
);
-
}
在Windows下面,在Visual Studio命令提示符下编译这个文件的命令是
cl /LD great_module.c /o great_module.pyd -IC:\Python27\include C:\Python27\libs\python27.lib
/LD 即生成动态链接库。编译成功后在当前目录可以得到 great_module.pyd(实际上是dll)。这个pyd可以在Python环境下直接当作module使用。
在Linux下面,则用gcc编译:
gcc -fPIC -shared great_module.c -o great_module.so -I/usr/include/python2.7/ -lpython2.7
在当前目录下得到great_module.so,同理可以在Python中直接使用。
本部分参考资料
easy_install -U cython
-
#great_module.pyx
-
cdef
public
great_function
(
a
,
index
):
-
return
a
[
index
]
cython great_module.pyx
-
__PYX_EXTERN_C
DL_IMPORT
(
PyObject
)
*
great_function
(
PyObject
*
,
PyObject
*
)
-
-
//main.c
-
#include
-
#include "great_module.h"
-
-
int
main
(
int
argc
,
char
*
argv
[])
{
-
PyObject
*
tuple
;
-
Py_Initialize
();
-
initgreat_module
();
-
printf
(
"%s
\n
"
,
PyString_AsString
(
-
great_function
(
-
PyString_FromString
(
"hello"
),
-
PyInt_FromLong
(
1
)
-
)
-
));
-
tuple
=
Py_BuildValue
(
"(iis)"
,
1
,
2
,
"three"
);
-
printf
(
"%d
\n
"
,
PyInt_AsLong
(
-
great_function
(
-
tuple
,
-
PyInt_FromLong
(
1
)
-
)
-
));
-
printf
(
"%s
\n
"
,
PyString_AsString
(
-
great_function
(
-
tuple
,
-
PyInt_FromLong
(
2
)
-
)
-
));
-
Py_Finalize
();
-
}
cl main.c great_module.c -IC:\Python27\include C:\Python27\libs\python27.lib
gcc main.c great_module.c -o main -I/usr/include/python2.7/ -lpython2.7
-
#great_module.pyx
-
cdef
public
char
great_function
(
const
char
*
a
,
int
index
):
-
return
a
[
index
]
__PYX_EXTERN_C DL_IMPORT(char) great_function(char const *, int);
-
//main.c
-
#include
-
#include "great_module.h"
-
-
int
main
(
int
argc
,
char
*
argv
[])
{
-
Py_Initialize
();
-
initgreat_module
();
-
printf
(
"%c"
,
great_function
(
"Hello"
,
2
));
-
Py_Finalize
();
-
}
-
#include
-
#include
-
#include "great_module.h"
-
-
extern
__declspec
(
dllexport
)
int
__stdcall
_great_function
(
const
char
*
a
,
int
b
)
{
-
return
great_function
(
a
,
b
);
-
}
-
-
BOOL
WINAPI
DllMain
(
HINSTANCE
hinstDLL
,
DWORD
fdwReason
,
LPVOID
lpReserved
)
{
-
switch
(
fdwReason
)
{
-
case
DLL_PROCESS_ATTACH
:
-
Py_Initialize
();
-
initgreat_module
();
-
break
;
-
case
DLL_PROCESS_DETACH
:
-
Py_Finalize
();
-
break
;
-
}
-
return
TRUE
;
-
}
cl /LD dllmain.c great_module.c -IC:\Python27\include C:\Python27\libs\python27.lib
-
/* File: mymodule.i */
-
%module mymodule
-
-
%{
-
#include "nmmintrin.h"
-
%}
-
-
int _mm_popcnt_u32(unsigned int v);
-
unsigned int _mm_crc32_u8 (unsigned int crc, unsigned char v);
-
unsigned int _mm_crc32_u16(unsigned int crc, unsigned short v);
-
unsigned int _mm_crc32_u32(unsigned int crc, unsigned int v);
swig -python mymodule.i
Windows:
cl /LD mymodule_wrap.c /o _mymodule.pyd -IC:\Python27\include C:\Python27\libs\python27.lib
Linux:
gcc -fPIC -shared mymodule_wrap.c -o _mymodule.so -I/usr/include/python2.7/ -lpython2.7
-
>>> import mymodule
-
>>> mymodule._mm_popcnt_u32(10)
-
2
还记得本文第2节的那个great_function吗?有了SWIG,事情就会变得如此简单:
-
/* great_module.i */
-
%module great_module
-
%{
-
int great_function(int a) {
-
return a + 1;
-
}
-
%}
-
int great_function(int a);
换句话说,SWIG自动完成了诸如Python类型转换、module初始化、导出代码表生成的诸多工作。
对于C++,SWIG也可以应对。例如以下代码有C++类的定义:
-
//great_class.h
-
#ifndef GREAT_CLASS
-
#define GREAT_CLASS
-
class
Great
{
-
private
:
-
int
s
;
-
public
:
-
void
setWall
(
int
_s
)
{
s
=
_s
;};
-
int
getWall
()
{
return
s
;};
-
};
-
#endif
// GREAT_CLASS
对应的SWIG配置文件
-
/* great_class.i */
-
%module great_class
-
%{
-
#include "great_class.h"
-
%}
-
%include "great_class.h"
这里不再重新敲一遍class的定义了,直接使用SWIG的%include指令
SWIG编译时要加-c++这个选项,生成的扩展名为cxx
swig -c++ -python great_class.i
cl /LD great_class_wrap.cxx /o _great_class.pyd -IC:\Python27\include C:\Python27\libs\python27.lib
Linux,使用C++的编译器
g++ -fPIC -shared great_class_wrap.cxx -o _great_class.so -I/usr/include/python2.7/ -lpython2.7
-
>>> import great_class
-
>>> c = great_class.Great()
-
>>> c.setWall(5)
-
>>> c.getWall()
-
5