示例:
https://www.cnblogs.com/pyse/p/8590829.html
修改示例(结构体:包含指针的联合体):
test1.py
#pycall.pyimport ctypes
from ctypes import *
class private_u(Union):
_fields_ = [("string" , c_char_p),
("integer", c_longlong),
("boolean", c_bool),
("floating", c_double)
]
class Student(Structure):
_fields_ = [("name",c_char * 30),
("fScore", c_int * 3),
("data", private_u)
]
su = Student()
su.name = b"test-sdk"
PARAM = c_int * 3
fScore = PARAM()
fScore[0] = 55
fScore[1] = 33
fScore[2] = 51
a = private_u()
a.integer =39
su.data =a
su.fScore = fScore
if __name__ == '__main__':
ll = cdll.LoadLibrary
lib = ll("./libpycall.so")
# lib.Display.restype = c_float
lib.Display.argtypes = [Student] #这一行很重要
lib.Display(su)
print('----- finish -----')
a.string = 'abcdefghij'.encode("utf-8")
su.data =a
lib.Display.argtypes = [Student] #这一行很重要
lib.Display(su)
print('----- finish 1-----')
a.floating = 39.21111111111111111
su.data =a
lib.Display.argtypes = [Student] #这一行很重要
lib.Display(su)
print('----- finish 2-----')
a.boolean = True
su.data =a
lib.Display.argtypes = [Student] #这一行很重要
lib.Display(su)
test1.c
//test1.c
# include <stdio.h>
# include <stdlib.h>
# include <stdbool.h>
union private_u{
char *string;
long long integer;
bool boolean;
double floating;
};
//创建一个Student结构体
struct Student
{
char name[30];
int fScore[3];
union private_u data;
};
void Display(struct Student su)
{
printf("-----Information------\n");
printf("Name:%s\n",su.name);
printf("Chinese:%d\n",su.fScore[0]);
printf("Math:%d\n",su.fScore[1]);
printf("English:%d\n",su.fScore[2]);
printf("总分数为:%d\n", su.fScore[0]+su.fScore[1]+su.fScore[2]);
printf("平均分数为:%d\n",((su.fScore[0]+su.fScore[1]+su.fScore[2]))/3);
// printf("data.string:%s\n",su.data.string);
printf("data.integer:%d\n",su.data.integer);
printf("data.boolean:%d\n",su.data.boolean);
printf("data.floating:%f\n",su.data.floating);
}
/*
struct attr_value {
union {
char *string;
int64 integer;
bool boolean;
double floating;
} private_u;
};
*/
version2: 传入通用数据并进行赋值
test1.py
#pycall.pyimport ctypes
from ctypes import *
class private_u(Union):
_fields_ = [("string" , c_char_p),
("integer", c_longlong),
("boolean", c_bool),
("floating", c_double)
]
class Student(Structure):
_fields_ = [("name",c_char_p),
("data", private_u)
]
su = Student()
#su.name = b"test-sdk"
a = private_u()
if __name__ == '__main__':
ll = cdll.LoadLibrary
lib = ll("./libpycall.so")
# lib.Display.restype = c_float
lib.Display.argtypes = [Student] #这一行很重要
lib.fun()
su.name = "aa".encode("utf-8")
a.integer =39
su.data =a
lib.Display(su)
su.name = "bb".encode("utf-8")
a.string ="this a char var".encode("utf-8")
su.data =a
lib.Display(su)
test1.cc
g++ -o libpycall.so -shared -fPIC test1.cc
//test1.c
# include <stdio.h>
# include <stdlib.h>
# include <stdbool.h>
#include<string>
#include<vector>
using namespace std;
union private_u{
char *string;
long long integer;
bool boolean;
double floating;
};
//创建一个Student结构体
struct Student
{
char *name;
union private_u data;
};
int aa;
char* bb;
struct var{
char *name;
private_u* ptr;
};
vector<var> vars;
#if defined(__cplusplus)
extern "C" {
#endif
void fun(){
var v1={"aa", (private_u*)&aa};
vars.push_back(v1);
var v2={"bb", (private_u*)&bb};
vars.push_back(v2);
}
void Display(struct Student su)
{
printf("-----Information------\n");
printf("Name:%s\n",su.name);
for(auto &a:vars){
printf("a.name:%s\n",a.name);
std::string str1 = a.name;
std::string str2 = su.name;
if(str1 ==str2){
*(a.ptr) =su.data;
}
}
printf("aa:%d\n",aa);
printf("bb:%s\n",bb);
//printf("aa:%d\n",su.data.integer);
}
#if defined(__cplusplus)
}
#endif
输出:
-----Information------
Name:aa
a.name:aa
a.name:bb
aa:39
bb:(null)
-----Information------
Name:bb
a.name:aa
a.name:bb
aa:39
bb:this a char var
test1.cc:使用map提升查找效率
//test1.c
# include <stdio.h>
# include <stdlib.h>
# include <stdbool.h>
#include<string>
#include<vector>
#include<map>
using namespace std;
union private_u{
char *string;
long long integer;
bool boolean;
double floating;
};
//创建一个Student结构体
struct Student
{
char *name;
union private_u data;
};
int aa;
char* bb;
struct var{
char *name;
private_u* ptr;
};
//vector<var> vars;
map<string , private_u* > vars;
#if defined(__cplusplus)
extern "C" {
#endif
void fun(){
// var v1={"aa", (private_u*)&aa};
// vars.push_back(v1);
// var v2={"bb", (private_u*)&bb};
// vars.push_back(v2);
vars["aa"]=(private_u*)&aa;
vars["bb"]=(private_u*)&bb;
}
void Display(struct Student su)
{
printf("-----Information------\n");
printf("Name:%s\n",su.name);
// for(auto &a:vars){
// printf("a.name:%s\n",a.name);
// std::string str1 = a.name;
// std::string str2 = su.name;
// if(str1 ==str2){
// *(a.ptr) =su.data;
// }
// }
std::string str = su.name;
*(vars[str]) =su.data;
printf("aa:%d\n",aa);
printf("bb:%s\n",bb);
//printf("aa:%d\n",su.data.integer);
}
#if defined(__cplusplus)
}
#endif
详解:
使用 ctypes 进行 Python 和 C 的混合编程:
https://www.cnblogs.com/gaowengang/p/7919219.html
补充:
python与C结构体之间数据转换:
https://www.cnblogs.com/iclodq/p/9216763.html
python3调用c函数接口的错误:
TypeError: bytes or integer address expected instead of str instance
utf8转换(OK了):
net = dn.load_net("cfg/yolov3.cfg".encode("utf-8"), "weights/yolov3.weights".encode("utf-8"), 0)