C语言调用云端 Python接口

本文介绍了如何使用C语言调用阿里云的Python接口进行垃圾分类识别,包括开启服务、改造Python脚本、C语言调用以及实验结果的展示,旨在帮助开发者理解和实践跨语言接口集成。
摘要由CSDN通过智能技术生成

利用C语言调用阿里云Python接口,来实现垃圾的智能识别

1、如何开启阿里云服务

大家可以自行在官网上面选择并开启,只有一次免费调用机会,于是我充了2块钱(恶毒的资本家)

垃圾分类识别常用语言和示例有哪些_视觉智能开放平台(VIAPI)-阿里云帮助中心 (aliyun.com)

2、实验程序介绍

2.1 py程序改造

  • 我们需要改造下阿里云提供给我们的代码,封装成一个函数,供后C程序调用

没学过Python也没关系,我们不需要改很多,有c的基础,知道.py文件是上面功能就ok。

# garbage.py
# -*- coding: utf-8 -*-
# 引入依赖包
# pip install alibabacloud_imagerecog20190930

import os
import io
from urllib.request import urlopen
from alibabacloud_imagerecog20190930.client import Client
from alibabacloud_imagerecog20190930.models import ClassifyingRubbishAdvanceRequest
from alibabacloud_tea_openapi.models import Config
from alibabacloud_tea_util.models import RuntimeOptions

config = Config(
  # 创建AccessKey ID和AccessKey Secret,请参考https://help.aliyun.com/document_detail/175144.html。
  # 如果您用的是RAM用户的AccessKey,还需要为RAM用户授予权限AliyunVIAPIFullAccess,请参考https://help.aliyun.com/document_detail/145025.html
  # 从环境变量读取配置的AccessKey ID和AccessKey Secret。运行代码示例前必须先配置环境变量。
  access_key_id=os.environ.get('ALIBABA_CLOUD_ACCESS_KEY_ID'),
  access_key_secret=os.environ.get('ALIBABA_CLOUD_ACCESS_KEY_SECRET'),
  # 访问的域名
  endpoint='imagerecog.cn-shanghai.aliyuncs.com',
  # 访问的域名对应的region
  region_id='cn-shanghai'
)

def alibaba_garbage(): # 封装成一个函数,方便其他文件调用
  #场景一:文件在本地
  ###
  img = open(r'/home/orangepi/garbage/lj/test2.jpg','rb')#这边是我们自定义的文件目录
  ###
  # img = open(r'/tmp/garbage.jpg','rb')
  #场景二:使用任意可访问的url
  # url = 'https://viapi-test-bj.oss-cn-beijing.aliyuncs.com/viapi-3.0domepic/imagerecog/ClassifyingRubbish/ClassifyingRubbish1.jpg'
  # img = io.BytesIO(urlopen(url).read())
  classifying_rubbish_request = ClassifyingRubbishAdvanceRequest()
  classifying_rubbish_request.image_urlobject = img
  runtime = RuntimeOptions()
  try:
    # 初始化Client
    client = Client(config)
    response = client.classifying_rubbish_advance(classifying_rubbish_request, runtime)
    # 获取整体结果
    # print(response.body) # 默认
    # print(response.body.to_map()) # 打印出body的类型
    print(response.body.to_map()['Data']['Elements'][0]['Category']) # 打印出body的类型
    return response.body.to_map()['Data']['Elements'][0]['Category']
    # 提供调用方便
  except Exception as error:
    # 获取整体报错信息
    # print(error)
    # 获取单个字段
    # print(error.code)
    return '获取失败'

if __name__== "__main__": #这是主函数哦
  alibaba_garbage() #调用我们前面封装的函数

2.2 c语言调用py

// garbage.c
// C语言引用Python文件
#if 0
/*
1、包含Python.h头文件,以便使用Python API。
2、使用void Py_Initialize()初始化Python解释器,
3、使用PyObject *PyImport_ImportModule(const char *name)和PyObject
*PyObject_GetAttrString(PyObject *o, const char *attr_name)获取sys.path对象,并利用
int PyList_Append(PyObject *list, PyObject *item)将当前路径.添加到sys.path中,以便加载
当前的Python模块(Python文件即python模块)。
4、使用PyObject *PyImport_ImportModule(const char *name)函数导入Python模块,并检查是否
有错误。
5、使用PyObject *PyObject_GetAttrString(PyObject *o, const char *attr_name)函数获取
Python函数对象,并检查是否可调用。
+6、使用PyObject *Py_BuildValue(const char *format, ...)函数将C类型的数据结构转换成
Python对象,作为Python函数的参数,没有参数不需要调用
7、使用PyObject *PyObject_CallObject(PyObject *callable, PyObject *args)函数调用
Python函数,并获取返回值。
+8、使用int PyArg_Parse(PyObject *args, const char *format, ...)函数将返回值转换为C类
型,并检查是否有错误,没有返回值时不需要调用。
9、使用void Py_DECREF(PyObject *o)函数释放所有引用的Python对象。
10、结束时调用void Py_Finalize()函数关闭Python解释器。
相关的函数参数说明参考网站(网站左上角输入函数名即可开始搜索):
https://docs.python.org/zh-cn/3/c-api/import.html
*/
#endif

#include <Python.h>
#include "garbage.h"


void garbage_init(void)
{
    Py_Initialize();
    // 将当前路径添加到sys.path中
    PyObject *sys = PyImport_ImportModule("sys");//初始化python解释器
    PyObject *path = PyObject_GetAttrString(sys, "path");
    PyList_Append(path, PyUnicode_FromString("."));
}

void garbage_final(void)
{
    //释放所有引用的Python对象
    Py_Finalize();
}
char *garbage_category(char *category)
{
    // 导入para模块
    PyObject *pModule = PyImport_ImportModule("garbage");//引用的是本目录底下的garbage.py文件
    if (!pModule)
    {
        PyErr_Print();
        printf("Error: failed to load para.py\n");
        goto FAILED_MODULE;
    }
    //获取 alibaba_garbage 函数对象
    PyObject *pFunc = PyObject_GetAttrString(pModule, "alibaba_garbage");
    //garbage.py文件里的这个函数 alibaba_garbage
    if (!pFunc)
    {
        PyErr_Print();
        printf("Error: failed to load say_funny\n");
        goto FAILED_FUNC;
    }

    //调用alibaba_garbage函数并获取返回值
    PyObject *pValue = PyObject_CallObject(pFunc, NULL);
    if (!pValue)
    {
        PyErr_Print();
        printf("Error: function call failed\n");
        goto FAILED_VALUE;
    } 
    //将返回值转换为C类型
    char *result = NULL;  //pValue(py) --> result(c)
    if (!PyArg_Parse(pValue, "s", &result))//PyArg_Parse根据指定的格式字符串将 Python 对象转换为 C 变量
    {
        PyErr_Print();
        printf("Error: parse failed\n");
        goto FAILED_RESULT;
    }
    //打印返回值
    printf("pValue=%s\n", result);
    category = (char*)malloc(sizeof(char)*(strlen(result)+1));//要留一个字节给 \0
    memset(category, 0, (strlen(result)+1));
    strncpy(category, result,(strlen(result)+1));//复制字符串
    

//会用来标识某个测试案例、任务或计划未能通过或达到预期的标准或目标;失败后跳转
FAILED_RESULT:
    Py_DECREF(pValue);
FAILED_VALUE:
    Py_DECREF(pFunc);
FAILED_FUNC:
    Py_DECREF(pModule);
FAILED_MODULE:

    return category;
}
  • 头文件也不能少
//garbage.h
#ifndef __GARBAGE__H
#define __GARBAGE__H
void garbage_init(void);//第一步做初始化,初始python的编译器包括导入当前路劲到sys.path里面
void garbage_final(void);
char *garbage_category(char *category);

#endif

2.3 测试代码

  • 我们来测试一下,先准备一张垃圾的图片
  • test2.c
    在这里插入图片描述
//garbagetest.c
#include <stdio.h>
#include <stdlib.h>
#include "garbage.h"

int main(int argc, char *argv[])
{
    char *category = NULL;
    garbage_init(); // 第一步做初始化,初始python的编译器包括导入当前 路劲到sys.path里面
    category = garbage_category(category);  
    // printf("category = %s\n",category);
    garbage_final();

    if(category)
        free(category);
    return 0;
}

3、实验结果

>>> gcc -o garbagetest garbagetest.c garbage.c garbage.h -I /usr/include/python3.10/ -l python3.10
>>> ./garbagetest

在这里插入图片描述



欢迎大家一起交流讨论!

要在C语言调用Python接口,可以使用Python的C API。下面是一个简单的示例代码,演示了如何在C语言调用Python的解释器和函数: ```c #include <Python.h> int main() { // 初始化Python解释器 Py_Initialize(); // 调用Python函数 PyObject* pyFuncName, * pyFuncArgs, * pyFuncResult; pyFuncName = PyUnicode_FromString("myPythonFunction"); pyFuncArgs = PyTuple_New(1); PyTuple_SetItem(pyFuncArgs, 0, PyLong_FromLong(123)); pyFuncResult = PyObject_CallObject(pyFuncName, pyFuncArgs); // 解析Python函数的返回值 long result = PyLong_AsLong(pyFuncResult); printf("Python function returned: %ld\n", result); // 释放Python对象 Py_DECREF(pyFuncName); Py_DECREF(pyFuncArgs); Py_DECREF(pyFuncResult); // 关闭Python解释器 Py_Finalize(); return 0; } ``` 在上面的代码中,我们首先调用`Py_Initialize()`函数初始化Python解释器。然后,我们使用`PyUnicode_FromString()`函数创建一个Python函数名的Python字符串对象,使用`PyTuple_New()`函数创建一个包含一个整数参数的Python元组对象,使用`PyObject_CallObject()`函数调用Python函数,并得到函数的返回值。最后,我们使用`PyLong_AsLong()`函数将Python返回值转换为C语言的长整型,并输出结果。最后,我们使用`Py_DECREF()`函数释放Python对象,然后使用`Py_Finalize()`函数关闭Python解释器。 需要注意的是,上面的代码只是一个简单的示例,实际上在实际应用中,还需要进行错误处理、异常处理等等。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值