ta.h
//__cplusplus和extern“C”一般都是配对使用,如果定义了__cplusplus(cpp文件默认定义了该宏),则采用C语言方式进行编译。
#ifdef __cplusplus
extern "C"{
#endif
#ifndef _TA_H_
#define _TA_H_
void test1(const char *ss);
#endif
#ifdef __cplusplus
}
#endif
ta.c
#include <stdio.h>
#include <stdlib.h>
#include "ta.h"
void test1(const char *ss){
printf("%s\n",ss);
}
编译
gcc -shared -fPIC -o libta.so ta.c
ta.py
import ctypes
from ctypes import *
ta = ctypes.CDLL('./libta.so')
test1 = ta.test1
ss = "abc"
test1(ss.encode("UTF-8"))
ta.h
//__cplusplus和extern“C”一般都是配对使用,如果定义了__cplusplus(cpp文件默认定义了该宏),则采用C语言方式进行编译。
#ifdef __cplusplus
extern "C"{
#endif
#ifndef _TA_H_
#define _TA_H_
int test2(int a);
float test3(float a);
double test4(double a);
#endif
#ifdef __cplusplus
}
#endif
ta.c
#include <stdio.h>
#include <stdlib.h>
#include "ta.h"
int test2(int a){
return a + 1;
}
float test3(float a){
return a+0.01;
}
double test4(double a){
return a+0.00003;
}
//gcc -shared -fPIC -o libta.so ta.c
ta.py
import ctypes
from ctypes import *
ta = ctypes.CDLL('./libta.so')
test2 = ta.test2
print(test2(2))
def c_test3(a):
ta.test3.argtype = [c_float]
ta.test3.restype = c_float
a = c_float(a)
res = ta.test3(a)
return round(res,6)
def c_test4(a):
ta.test4.argtype = [c_double]
ta.test4.restype = c_double
a = c_double(a)
res = ta.test4(a)
return round(res,8)
print("float com:",c_test3(1)) #float com: 1.01
print("double com:",c_test4(1)) #double com: 1.00003
ta.h
//__cplusplus和extern“C”一般都是配对使用,如果定义了__cplusplus(cpp文件默认定义了该宏),则采用C语言方式进行编译。
#ifdef __cplusplus
extern "C"{
#endif
#ifndef _TA_H_
#define _TA_H_
void test1(const char *ss);
int test2(int a);
typedef struct ROW_Struct{
int id;
float f;
double d;
char* name;
char* card_num;
char* card_time;
}Row,*ROW;
Row get_row();
ROW get_row_pointer();
void print_row(Row row);
void free_row(Row *p);
#endif
#ifdef __cplusplus
}
#endif
ta.c
#include <stdio.h>
#include <stdlib.h>
#include "ta.h"
void test1(const char *ss){
printf("%s\n",ss);
}
int test2(int a){
return a + 1;
}
Row get_row(){
Row row;
row.id = 11;
row.name = "卧龙在渊";
row.card_num = "62200248001235632";
row.card_time = "2023-10-01 10:10:10";
return row;
}
ROW get_row_pointer(){
Row* row = NULL;
row = (Row *)malloc(sizeof(Row));
row->id = 12;
row->name = "飞龙在天";
row->card_num = "62208480012345632";
row->card_time = "2023-10-09 11:11:11";
return row;
}
void print_row(Row row){
float f = row.f+0.1;
double d = row.d + 0.001;
printf("row f:%f\n",f);
printf("row d:%lf\n",d);
printf("row name:%s\n",row.name);
}
void free_row(Row *p){
if(p != NULL){
printf("begin free:%s\n",p->name);
free(p);
p=NULL;
}
}
//gcc -shared -fPIC -o libta.so ta.c
ta.py
import ctypes
from ctypes import *
ta = ctypes.CDLL('./libta.so')
# 字符串输入时传入的是字节,从C中返回的也是字节
ss = "abc"
test1 = ta.test1
test1(ss.encode("UTF-8"))
test2 = ta.test2
print(test2(2))
class PyRow(Structure):
_fields_ = [
("id",c_int),
("f",c_float),
("d",c_double),
("name",c_char_p),
("card_num",c_char_p),
("card_time",c_char_p),
]
get_row = ta.get_row
get_row.restype = PyRow # 设置函数返回结果的类型为结构体
r1 = get_row()
print(r1.id) #11
print(r1.name.decode("UTF-8"))
print(type(r1.card_num),r1.card_num.decode("UTF-8")) # class 'bytes' 62200248001235632
print(r1.card_time.decode("UTF-8")) # 2023-10-01 10:10:10
# 字符串输入时传入的是字节,从C中返回的也是字节
row = PyRow(id=13,name="亢龙有悔".encode("UTF-8"),card_num="6223002342876324".encode("UTF-8"),card_time="2009-09-09 09:09:09".encode("UTF-8"))
print_row = ta.print_row
print_row(row) # row name:亢龙有悔
get_row_pointer = ta.get_row_pointer
get_row_pointer.restype = POINTER(PyRow) # 设置函数返回结果的类型为结构体指针
p = get_row_pointer()
print("p:",p.contents.id)
print("p:",p.contents.name.decode("utf-8")) # p: fei long zai tian
# 在C中使用malloc分配了内存空间,还得去free一下
free_row = ta.free_row
free_row(p)
python调用C语言动态链接库详解
Python与C数据类型关系/定义结构和联合