使用c语言扩展python第一篇,返回不同类型

项目目录结构:

 

xuxiaobo.c内容:

#include <Python.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int count_substrings(const char *str, const char *delim) {
    int count = 0;
    char *token = strtok((char *)str, delim); // 注意这里的强制类型转换
    while (token != NULL) {
        count++;
        token = strtok(NULL, delim); // 继续分割剩余的字符串
    }
    return count;
}

//定义打招呼函数
static PyObject* xuxiaobo_hello(PyObject* self, PyObject* args) {
    char *name;
    char *dest = malloc(1024);
    if (!PyArg_ParseTuple(args, "s", &name)) {
        return NULL;
    }

    /*
    strcpy(dest, "");
    strcat(dest, "hello, ");
    strcat(dest, name);
    strcat(dest, "!");
    */

    sprintf(dest, "你好, %s!", name);

    return Py_BuildValue("s", dest);
}

//定义计算平方函数
static PyObject* xuxiaobo_square(PyObject* self, PyObject* args) {
    int num;
    if (!PyArg_ParseTuple(args, "i", &num)) {
        return NULL;
    }
    return Py_BuildValue("i", num * num);
}

//定义计算立方函数
static PyObject* xuxiaobo_cube(PyObject* self, PyObject* args) {
    double num;
    if (!PyArg_ParseTuple(args, "d:xuxiaobo_cube", &num)) {
        return NULL;
    }
    return Py_BuildValue("d", num * num * num);
}

//定义解析url参数函数
static PyObject* xuxiaobo_parse_url(PyObject* self, PyObject* args) {
	char *params_str;
	char *delim = "=&,. ";
	PyObject* pDict = PyDict_New();

    if (!PyArg_ParseTuple(args, "s", &params_str)) {
        return NULL;
    }

	int i = 0;
    char *token = strtok(params_str, delim);
    while (token != NULL) {
    	char key[1024];
    	char value[1024];
		if(i%2 == 0){
			strcpy(key, token);
			//printf("debug key=>%s\n", key);
		} else{
			strcpy(value, token);
			//printf("debug value=>%s\n", value);
			PyDict_SetItemString(pDict, key, Py_BuildValue("s", value));
		}
		token = strtok(NULL, delim);
    	i++;
    }
	//printf("i=>%d\n", i);

    return pDict;
}

//定义字符串切分函数,返回list
static PyObject* xuxiaobo_split_str_list(PyObject* self, PyObject* args) {
	char *params_str;
	char *delim = "&,. ";
	PyObject* plist = PyList_New(0);

    if (!PyArg_ParseTuple(args, "s", &params_str)) {
        return NULL;
    }

    char *token = strtok(params_str, delim);
    while (token != NULL) {
		PyList_Append(plist, Py_BuildValue("s", token));
		token = strtok(NULL, delim);
    }

    return plist;
}

//定义字符串切分函数,返回tuple
static PyObject* xuxiaobo_split_str_tuple(PyObject* self, PyObject* args) {
	char *delim = "&,. ";
	char *params_str;
	char params_str_tmp[1024];

    if (!PyArg_ParseTuple(args, "s", &params_str)) {
        return NULL;
    }

    strcpy(params_str_tmp, params_str);
	int max = count_substrings(params_str_tmp, delim);
	PyObject* ptuple = PyTuple_New(max);

    int i = 0;
    char *token = strtok(params_str, delim);
    while (token != NULL && i < max) {
    	//printf("[%d]debug=>%s\n", i, token);
    	PyTuple_SetItem(ptuple, i, Py_BuildValue("s", token));
		token = strtok(NULL, delim);
		i++;
    }

    return ptuple;
}

//定义字符串切分函数,返回set
static PyObject* xuxiaobo_split_str_set(PyObject* self, PyObject* args) {
	char *delim = "&,. ";
	char *params_str;
	PyObject* pset = PySet_New(NULL);

    if (!PyArg_ParseTuple(args, "s", &params_str)) {
        return NULL;
    }

    int i = 0;
    char *token = strtok(params_str, delim);
    while (token != NULL) {
    	//printf("[%d]debug=>%s\n", i, token);
    	if(PySet_Add(pset, Py_BuildValue("s", token)) == -1){
    		Py_DECREF(pset);
    		return NULL;
    	}
		token = strtok(NULL, delim);
		i++;
    }

    return pset;
}

//定义季节检测函数,返回bool
static PyObject* xuxiaobo_is_season(PyObject* self, PyObject* args) {
	char *params_str;
	char params_str_tmp[1024];

    if (!PyArg_ParseTuple(args, "s", &params_str)) {
        return NULL;
    }

    strcpy(params_str_tmp, params_str);

    if(strcmp(params_str_tmp, "春") == 0 ||
       strcmp(params_str_tmp, "夏") == 0 ||
	   strcmp(params_str_tmp, "秋") == 0 ||
	   strcmp(params_str_tmp, "东") == 0){
        return PyBool_FromLong(1);
    }

    return PyBool_FromLong(0);
}

static PyMethodDef XuxiaoboMethods[] = {
	{"hello", xuxiaobo_hello, METH_VARARGS, NULL},
    {"square", xuxiaobo_square, METH_VARARGS, NULL},
	{"cube", xuxiaobo_cube, METH_VARARGS, NULL},
    {"parse_url",  xuxiaobo_parse_url, METH_VARARGS, NULL},
    {"split_str_list", xuxiaobo_split_str_list, METH_VARARGS, NULL},
    {"split_str_tuple", xuxiaobo_split_str_tuple, METH_VARARGS, NULL},
    {"split_str_set", xuxiaobo_split_str_set, METH_VARARGS, NULL},
    {"is_season", xuxiaobo_is_season, METH_VARARGS, NULL},
    {NULL, NULL, 0, NULL}
};

static struct PyModuleDef xuxiaobomodule = {
    PyModuleDef_HEAD_INIT,
    "xuxiaobo",
    NULL,
    -1,
	XuxiaoboMethods
};

PyMODINIT_FUNC PyInit_xuxiaobo(void) {
    return PyModule_Create(&xuxiaobomodule);
}

  

setup.py内容:

from setuptools import setup, Extension

'''
程序源码中有中文,可以指定cl.exe 参数
'''
my_module = Extension('xuxiaobo', sources=['xuxiaobo.c'], extra_compile_args=['/source-charset:utf-8', '/execution-charset:utf-8'])

setup(
    name='xuxiaobo',
    version='1.0',
    description='徐小波测试使用c语言扩展python',
    ext_modules=[my_module],
)

  

test.py内容:

#coding=utf-8

from xuxiaobo import *


my_str = hello("徐小波")
print(type(my_str))
print(my_str)
print()

my_square = square(3)
print(type(my_square))
print(my_square)
print()

my_cube = cube(3.0)
print(type(my_cube))
print(my_cube)
print()

my_dict = parse_url("a=1&b=2&c=3&d=我爱北京天安门")
print(type(my_dict))
print(my_dict)
print()

my_list = split_str_list("河.北.大.学.徐,小 波")
print(type(my_list))
print(my_list)
print()

my_tuple = split_str_tuple("河.北.大.学.徐,小.波 啊")
print(type(my_tuple))
print(my_tuple)
print()

my_set = split_str_set("河.北.大 学.河.北.大 学 河.北.大 学")
print(type(my_set))
print(my_set)
print()

my_bool = is_season("夏")
print(type(my_bool))
print(my_bool)
print()

  

编译模块

python setup.py build

 

 

安装模块

python setup.py install

 

 

 

 

 

测试结果:

 

 

 

此例旨在对各种数据类型的输出实践一遍。

 

 

posted @ 2025-07-09 18:28  河北大学-徐小波  阅读(231)  评论(0)    收藏  举报