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数据类型关系/定义结构和联合