示例1:
pycallclass.cpp:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
|
#include <iostream>
using namespace std;
typedef unsigned char BYTE;
#define MAX_COUNT 20
struct tagOutCardResult_py
{
BYTE cbCardCount;
BYTE cbResultCard1;
BYTE cbResultCard2;
BYTE cbResultCard3;
BYTE cbResultCard4;
BYTE cbResultCard5;
BYTE cbResultCard6;
BYTE cbResultCard7;
BYTE cbResultCard8;
BYTE cbResultCard9;
BYTE cbResultCard10;
BYTE cbResultCard11;
BYTE cbResultCard12;
BYTE cbResultCard13;
BYTE cbResultCard14;
BYTE cbResultCard15;
BYTE cbResultCard16;
BYTE cbResultCard17;
BYTE cbResultCard18;
BYTE cbResultCard19;
BYTE cbResultCard20;
};
struct tagOutCardResult
{
BYTE cbCardCount;
BYTE cbResultCard[MAX_COUNT];
void clear()
{
cbCardCount = 0 ;
for ( int nIdx = 0 ;nIdx < MAX_COUNT; + + nIdx)
{
cbResultCard[nIdx] = 0 ;
}
}
void topy(tagOutCardResult_py * ppy)
{
cout<< "topy function begin" <<endl;
ppy - >cbCardCount = cbCardCount;
cout<< "topy function 1" <<endl;
ppy - >cbResultCard1 = cbResultCard[ 1 - 1 ];
cout<< "topy function 2" <<endl;
ppy - >cbResultCard2 = cbResultCard[ 2 - 1 ];
ppy - >cbResultCard3 = cbResultCard[ 3 - 1 ];
ppy - >cbResultCard4 = cbResultCard[ 4 - 1 ];
ppy - >cbResultCard5 = cbResultCard[ 5 - 1 ];
ppy - >cbResultCard6 = cbResultCard[ 6 - 1 ];
ppy - >cbResultCard7 = cbResultCard[ 7 - 1 ];
ppy - >cbResultCard8 = cbResultCard[ 8 - 1 ];
ppy - >cbResultCard9 = cbResultCard[ 9 - 1 ];
ppy - >cbResultCard10 = cbResultCard[ 10 - 1 ];
ppy - >cbResultCard11 = cbResultCard[ 11 - 1 ];
ppy - >cbResultCard12 = cbResultCard[ 12 - 1 ];
ppy - >cbResultCard13 = cbResultCard[ 13 - 1 ];
ppy - >cbResultCard14 = cbResultCard[ 14 - 1 ];
ppy - >cbResultCard15 = cbResultCard[ 15 - 1 ];
ppy - >cbResultCard16 = cbResultCard[ 16 - 1 ];
ppy - >cbResultCard17 = cbResultCard[ 17 - 1 ];
ppy - >cbResultCard18 = cbResultCard[ 18 - 1 ];
ppy - >cbResultCard19 = cbResultCard[ 19 - 1 ];
ppy - >cbResultCard20 = cbResultCard[ 20 - 1 ];
cout<< "topy function end" <<endl;
}
};
class TestLib
{
public:
void display(tagOutCardResult& ret);
};
void TestLib::display(tagOutCardResult& ret) {
ret.cbCardCount = 3 ;
ret.cbResultCard[ 0 ] = 1 ;
ret.cbResultCard[ 1 ] = 50 ;
ret.cbResultCard[ 2 ] = 100 ;
cout<< "First display aaa " ;
cout<< "hello " ;
cout<< "world " ;
}
extern "C" {
TestLib oGameLogic;
void display(tagOutCardResult_py * ret_py) {
tagOutCardResult oRet;
oGameLogic.display(oRet);
cout<< "before topy" <<endl;
oRet.topy(ret_py);
cout<< "after topy" <<endl;
cout<< "in cpp:ret_py->cbCardCount:" <<ret_py - >cbCardCount<<endl;
cout<< "in cpp:ret_py->cbResultCard1:" <<ret_py - >cbResultCard1<<endl;
cout<< " this:" << ret_py << endl;
}
}
|
编译脚本:
g++ -o libpycallclass.so -shared -fPIC pycallclass.cpp -I/usr/include/python2.6 -L/usr/lib64/python2.6/config
Game.py调用部分。类声明:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
import ctypes
class tagOutCardResult_py(ctypes.Structure):
_fields_ = [( "cbCardCount" , ctypes.c_ubyte), \
( "cbResultCard1" , ctypes.c_ubyte), \
( "cbResultCard2" , ctypes.c_ubyte), \
( "cbResultCard3" , ctypes.c_ubyte), \
( "cbResultCard4" , ctypes.c_ubyte), \
( "cbResultCard5" , ctypes.c_ubyte), \
( "cbResultCard6" , ctypes.c_ubyte), \
( "cbResultCard7" , ctypes.c_ubyte), \
( "cbResultCard8" , ctypes.c_ubyte), \
( "cbResultCard9" , ctypes.c_ubyte), \
( "cbResultCard10" , ctypes.c_ubyte), \
( "cbResultCard11" , ctypes.c_ubyte), \
( "cbResultCard12" , ctypes.c_ubyte), \
( "cbResultCard13" , ctypes.c_ubyte), \
( "cbResultCard14" , ctypes.c_ubyte), \
( "cbResultCard15" , ctypes.c_ubyte), \
( "cbResultCard16" , ctypes.c_ubyte), \
( "cbResultCard17" , ctypes.c_ubyte), \
( "cbResultCard18" , ctypes.c_ubyte), \
( "cbResultCard19" , ctypes.c_ubyte), \
( "cbResultCard20" , ctypes.c_ubyte)]
|
Game.py调用部分。具体调用:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
import ctypes
so = ctypes.cdll.LoadLibrary
lib = so("./libpycallclass.so")
ERROR_MSG('display(\)')
ret = tagOutCardResult_py(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
ERROR_MSG("before lib.display(ctypes.byref(ret))")
lib.display(ctypes.byref(ret))
ERROR_MSG("after lib.display(ctypes.byref(ret))")
ERROR_MSG('#######################################################################################')
ERROR_MSG(ret)
ERROR_MSG(ret.cbCardCount)
ERROR_MSG(ret.cbResultCard1)
ERROR_MSG(ret.cbResultCard2)
ERROR_MSG(ret.cbResultCard3)
ERROR_MSG(type(ret))
|
传入一个结构体,使用引用返回,回到python中打印出来结果是对的。
这样就可以传入,可以传出了。
示例1end#########################################################################
示例2:
pycallclass.cpp:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
|
#include <iostream>
using namespace std;
typedef unsigned char BYTE;
#define MAX_COUNT 20
#if defined(WIN32)||defined(WINDOWS)
#define DLL_EXPORT __declspec(dllexport)
#else
#define DLL_EXPORT
#endif
struct ByteArray_20
{
BYTE e1;
BYTE e2;
BYTE e3;
BYTE e4;
BYTE e5;
BYTE e6;
BYTE e7;
BYTE e8;
BYTE e9;
BYTE e10;
BYTE e11;
BYTE e12;
BYTE e13;
BYTE e14;
BYTE e15;
BYTE e16;
BYTE e17;
BYTE e18;
BYTE e19;
BYTE e20;
};
struct ByteArray_20_3
{
ByteArray_20 e1;
ByteArray_20 e2;
ByteArray_20 e3;
};
struct ByteArrayNew_20_3
{
BYTE e[ 3 ][ 20 ];
};
class TestLib
{
public:
void LogicFunc(ByteArray_20_3& ret);
void LogicFuncNew(ByteArrayNew_20_3& ret);
};
void TestLib::LogicFunc(ByteArray_20_3& ret) {
ret.e1.e1 = 3 ;
ret.e1.e2 = 1 ;
ret.e1.e3 = 50 ;
ret.e2.e1 = 100 ;
ret.e2.e2 = 200 ;
ret.e2.e3 = 20 ;
cout<< "TestLib::LogicFunc" <<endl;
}
void TestLib::LogicFuncNew(ByteArrayNew_20_3& ret) {
ret.e[ 0 ][ 0 ] = 31 ;
ret.e[ 0 ][ 1 ] = 11 ;
ret.e[ 0 ][ 2 ] = 51 ;
ret.e[ 1 ][ 0 ] = 101 ;
ret.e[ 1 ][ 1 ] = 201 ;
ret.e[ 1 ][ 2 ] = 21 ;
cout << "TestLib::LogicFuncNew" << endl;
}
extern "C" {
TestLib oGameLogic;
void DLL_EXPORT display(ByteArray_20_3 * pret) {
cout<< "cpp display func begin" <<endl;
oGameLogic.LogicFunc( * pret);
cout<< "cpp display func end" <<endl;
}
void DLL_EXPORT display2(ByteArrayNew_20_3 * pret) {
cout << "cpp display2 func begin" << endl;
oGameLogic.LogicFuncNew( * pret);
cout << "cpp display2 func end" << endl;
}
}
|
pycallclass.py:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
|
import ctypes
def ERROR_MSG( str ):
print str
class ByteArray_20(ctypes.Structure):
_fields_ = [\
( "e1" , ctypes.c_ubyte), \
( "e2" , ctypes.c_ubyte), \
( "e3" , ctypes.c_ubyte), \
( "e4" , ctypes.c_ubyte), \
( "e5" , ctypes.c_ubyte), \
( "e6" , ctypes.c_ubyte), \
( "e7" , ctypes.c_ubyte), \
( "e8" , ctypes.c_ubyte), \
( "e9" , ctypes.c_ubyte), \
( "e10" , ctypes.c_ubyte), \
( "e11" , ctypes.c_ubyte), \
( "e12" , ctypes.c_ubyte), \
( "e13" , ctypes.c_ubyte), \
( "e14" , ctypes.c_ubyte), \
( "e15" , ctypes.c_ubyte), \
( "e16" , ctypes.c_ubyte), \
( "e17" , ctypes.c_ubyte), \
( "e18" , ctypes.c_ubyte), \
( "e19" , ctypes.c_ubyte), \
( "e20" , ctypes.c_ubyte)]
class ByteArray_20_3(ctypes.Structure):
_fields_ = [\
( "e1" , ByteArray_20), \
( "e2" , ByteArray_20), \
( "e3" , ByteArray_20)]
def __init__( self ):
self .aaa = 123
self .bbb = [ 1 , 2 , 3 , 4 , 5 ]
self .ccc = "alksdfjlasdfjk"
def test( self ):
self .aaa = 123
self .bbb = [ 1 , 2 , 3 , 4 , 5 ]
self .ccc = "alksdfjlasdfjk"
self .e1.e1 = 5
self .e1.e2 = 20
so = ctypes.cdll.LoadLibrary
lib = so( "./libpycallclass.dll" )
print ( 'display()' )
ret = ByteArray_20_3()
ret.test()
ERROR_MSG(ret.e1.e1)
ERROR_MSG(ret.e1.e2)
print ( "before lib.display(ctypes.byref(ret))" )
lib.display(ctypes.byref(ret))
print ( "after lib.display(ctypes.byref(ret))" )
print ( '#######################################################################################' )
print (ret)
ERROR_MSG(ret.e1)
ERROR_MSG(ret.e2)
ERROR_MSG(ret.e3)
ERROR_MSG(ret.e1.e1)
ERROR_MSG(ret.e1.e2)
ERROR_MSG(ret.e1.e3)
ERROR_MSG(ret.e2.e1)
ERROR_MSG(ret.e2.e2)
ERROR_MSG(ret.e2.e3)
ERROR_MSG( type (ret))
print ( "before lib.display2(ctypes.byref(ret))" )
lib.display2(ctypes.byref(ret))
print ( "after lib.display2(ctypes.byref(ret))" )
print ( '#######################################################################################' )
print (ret)
ERROR_MSG(ret.e1)
ERROR_MSG(ret.e2)
ERROR_MSG(ret.e3)
ERROR_MSG(ret.e1.e1)
ERROR_MSG(ret.e1.e2)
ERROR_MSG(ret.e1.e3)
ERROR_MSG(ret.e2.e1)
ERROR_MSG(ret.e2.e2)
ERROR_MSG(ret.e2.e3)
ERROR_MSG( type (ret))
ret.test()
ERROR_MSG(ret.e1.e1)
ERROR_MSG(ret.e1.e2)
|
g++:
g++ -o libpycallclass.so -shared -fPIC pycallclass.cpp -I/usr/include/python2.6 -L/usr/lib64/python2.6/config
windows:
新建一个DLL工程,把pycallclass.cpp加进去,编译成DLL就OK了。
千万注意python的运行时是32位的还是64位的,DLL或者SO必须和它对应。
python类可以嵌套使用,继承ctypes.Structure,部分成员是_fields_里定义的,部分成员在__init__里定义,这样的类也可以ctypes.byref(self)传进c++去,传的是指针,传入传出就都OK了。
注意示例2中ByteArrayNew_20_3的用法,python中是定义了20个变量,c++中是直接一个二维数组。内存结构是一致的,所以可以直接这样使用。注意类型和长度必须一致,否则可能会内存访问越界。
以上这篇python调用c++ ctype list传数组或者返回数组的方法就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持服务器之家。
原文链接:https://blog.csdn.net/uniqsa/article/details/78603082