本文提供Python以链接库的形式调用C函数的实例。主要用到Python提供的ctypes实现。Python官方教程地址:Ctypes
范例一:Python 调用 C 语言 so
第一步:编写C函数,testlib.c
1
2
3
4
5
|
#include <stdio.h>
void
myprint
(
)
{
printf
(
"hello,www.cricode.com!n"
)
;
}
|
第二步:将C函数编译成链接库
1
2
3
|
$
gcc
-
shared
-
Wl
,
-
soname
,
testlib
-
o
testlib
.
so
-
fPIC
testlib
.
c
如果在
Mac
OS
X
,则
$
gcc
-
shared
-
Wl
,
-
install_name
,
testlib
.
so
-
o
testlib
.
so
-
fPIC
testlib
.
c
|
第三步:在python中使用C链接库函数,编写python代码test.py如下
1
2
3
4
|
import
ctypes
testlib
=
ctypes
.
CDLL
(
'/path/to/testlib.so'
)
testlib
.
myprint
(
)
|
第四步:just run it
1
2
|
$
python
test
.
py
hello
,
www
.
cricode
.
com
!
|
范例二:参数类型为字符串(即传指针)
当C函数中,参数类型为字符串时,使用ctypes提供的create_string_buffer来创建缓存区。
第一步:编写C函数testlib1.c
1
2
3
4
5
6
7
8
9
10
11
|
#include <string.h>
int
reverse
(
char
*
str
)
{
int
i
,
j
,
t
;
for
(
i
=
0
,
j
=
strlen
(
str
)
-
1
;
i
<
j
;
i
++
,
j
--
)
{
t
=
str
[
i
]
;
str
[
i
]
=
str
[
j
]
;
str
[
j
]
=
t
;
}
return
0
;
}
|
第二步:将C函数编译成链接库
1
|
$
gcc
-
shared
-
Wl
,
-
soname
,
testlib1
-
o
testlib1
.
so
-
fPIC
testlib1
.
c
|
第三步:在python中使用C链接库函数,编写python代码test1.py如下:
1
2
3
4
5
6
7
8
|
import
ctypes
s0
=
'hello,www.cricode.com'
s1
=
ctypes
.
create_string_buffer
(
s0
)
testlib1
=
ctypes
.
CDLL
(
'./testlib1.so'
)
testlib1
.
reverse
(
s0
)
print
's0 is: '
,
s0
print
's1 is: '
,
s1
.
value
|
第四步:just run it
1
2
3
|
$
python
test1
.
py
s0
is
:
moc
.
edocirc
.
www
,
olleh
s1
is
:
hello
,
www
.
cricode
.
com
|
范例三:参数为指针、数组(传指针、数组)
第一步:编写C函数testlib2.c
1
2
3
4
|
void
arrayFunc
(
int
*
sum
,
int
arr
[
4
]
)
{
*
sum
=
arr
[
0
]
+
arr
[
1
]
*
2
+
arr
[
2
]
*
3
+
arr
[
3
]
*
4
;
}
|
第二步:将C函数编译成链接库
1
|
$
gcc
-
shared
-
Wl
,
-
soname
,
testlib2
-
o
testlib2
.
so
-
fPIC
testlib2
.
c
|
第三步:在python中使用C链接库函数,
1
2
3
4
5
6
7
8
9
10
|
import
ctypes
result
=
ctypes
.
c_int
(
)
array
=
ctypes
.
c_int*
4
parray
=
array
(
ctypes
.
c_int
(
1
)
,
ctypes
.
c_int
(
2
)
,
ctypes
.
c_int
(
3
)
,
ctypes
.
c_int
(
4
)
)
testlib2
=
ctypes
.
CDLL
(
'./testlib2.so'
)
#testlib2.arrayFunc.argtypes=[ctypes.c_void_p,ctypes.c_int*4]
testlib2
.
arrayFunc
(
ctypes
.
pointer
(
result
)
,
parray
)
print
'result is:'
,
result
.
value
|
第四步:just run it
1
2
|
$
python
test2
.
py
result
is
:
17
|
范例四 参数为结构体
第一步:编写C函数testlib3.c
编写python代码test2.py如下:
1
2
3
4
5
6
7
8
9
10
11
|
typedef
struct
{
int
x
;
int
y
;
}
mystruct
;
mystruct
structFunc
(
mystruct
a
,
mystruct
b
)
{
mystruct
s
;
s
.
x
=
a
.
x
+
b
.
x
;
s
.
y
=
a
.
y
+
b
.
y
;
return
s
;
}
|
第二步:将C函数编译成链接库
1
|
$
gcc
-
shared
-
Wl
,
-
soname
,
testlib3
-
o
testlib3
.
so
-
fPIC
testlib3
.
c
|
第三步:在python中使用C链接库函数,编写python代码test3.py如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
|
import
ctypes
class
mystruct
(
ctypes
.
Structure
)
:
_fields_
=
[
(
"x"
,
ctypes
.
c_int
)
,
(
"y"
,
ctypes
.
c_int
)
]
a
=
mystruct
(
2
,
4
)
b
=
mystruct
(
4
,
6
)
testlib3
=
ctypes
.
CDLL
(
'./testlib3.so'
)
#srestype muste be setted to avoid segment fault
testlib3
.
structFunc
.
restype
=
mystruct
c
=
testlib3
.
structFunc
(
a
,
b
)
print
c
.
x
,
c
.
y
|
第四步:just run it
1
2
|
$
python
test3
.
py
6
10
|
范例五 回调函数的使用
回调函数是什么?
回调函数是由你自己定义,但你永远也不会调用它的一类函数的总称。
【也就是说,你是活雷锋,你在给别人做嫁衣】
continue….