ctypes 字符串举例

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"))

ctypes 数字

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

ctypes 结构体

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)

ctypes 数据类型对照表
ctypes数据类型对照表
参考文章
    python调用C语言动态链接库详解

    Python与C数据类型关系/定义结构和联合