Xcode 项目内 OC 混编 Python,调用 Python 函数,并获取返回值(基于 python 的 c函数库)

1:新建 Xcode 工程
2:工程添加 Python.framework


1597052861430.jpg

3:在当前工程下新建一个名字为 googleT 的 python 文件(googleT.py)


1597052584962.jpg

在 googleT.py 文件内写入一个测试 python 函数


def lgf_translate( str ):
    var1 = ' Hello World!'
    print (str + var1)
    return (str + var1)

4:新建一个 OC 类 GoogleTranslate 名字随意
直接上代码
.h

//
//  GoogleTranslate.h
//  LGFFY
//
//  Created by lai on 2020/7/23.
//  Copyright © 2020 victor. All rights reserved.
//

#import <Foundation/Foundation.h>

NS_ASSUME_NONNULL_BEGIN

@interface GoogleTranslate : NSObject
- (NSString *)pyCallWithModule:(char *)module funcKey:(char *)funcKey Args:(char *)args;
@end

NS_ASSUME_NONNULL_END

.m

//
//  GoogleTranslate.m
//  LGFFY
//
//  Created by lai on 2020/7/23.
//  Copyright © 2020 victor. All rights reserved.
//

#import "GoogleTranslate.h"
#import <Python/Python.h>

@interface GoogleTranslate()
@end
@implementation GoogleTranslate

/**
 OC 调用 Python (基于 c/c++ 调用 Python)
 
 @param module python 模块名称
 @param funcKey 函数名称
 @param args 函数参数
 @return 返回值
 */
- (NSString *)pyCallWithModule:(char * _Nonnull)module funcKey:(char * _Nonnull)funcKey Args:(char * _Nonnull)args {
    
    // 初始化 python 解释器
    Py_Initialize();
    if (!Py_IsInitialized()) {
        return @"error: 初始化环境失败";
    }
    
    // 新增 python 路径这里的新增路径是 xcode 内 python 文件的路径, 这一步很关键, 不设置 python 环境将无法检测到 xcode 工程下的 python 模块
    PySys_SetPath((char *)[[NSString stringWithFormat:@"%s:%@", Py_GetPath(), [[NSBundle mainBundle] resourcePath]] UTF8String]);
    
    // 初始化参数
    PyObject *pModule = NULL, *pFunc = NULL, *pDict = NULL, *pValue = NULL, *pResult = NULL;

    pModule = PyImport_ImportModule(module);
    if (!pModule) {
        finalize(pModule ,pFunc ,pDict ,pValue, pResult);
        return [NSString stringWithFormat:@"error: %s 模块找不到", module];
    }
    
    // 使用PyObject* pDict来存储导入模块中的方法字典
    pDict = PyModule_GetDict(pModule);
    if(!pDict) {
        finalize(pModule ,pFunc ,pDict ,pValue, pResult);
        return [NSString stringWithFormat:@"error: %s 模块中未定义方法", module];
    }
    
    // 获取模块中的函数
    pFunc = PyDict_GetItemString(pDict, funcKey);
    if(!pFunc || !PyCallable_Check(pFunc)) {
        finalize(pModule ,pFunc ,pDict ,pValue, pResult);
        return @"error: 方法获取失败";
    }
    
    // 函数参数
    pValue = Py_BuildValue("(z)", args);
    if(!pValue) {
        finalize(pModule ,pFunc ,pDict ,pValue, pResult);
        return @"error: 参数转换失败";
    }
    // 调用函数获取 return 值
    pResult = PyObject_CallObject(pFunc, pValue);
    if (!pResult) {
        finalize(pModule ,pFunc ,pDict ,pValue, pResult);
        return @"error: return 值出错";
    }
    
    //结果处理
    if (PyString_Check(pResult)) {
        finalize(pModule ,pFunc ,pDict ,pValue, pResult);
        return [NSString stringWithUTF8String: PyString_AsString(pResult)];
    } else if (PyInt_Check(pResult)) {
        finalize(pModule ,pFunc ,pDict ,pValue, pResult);
        return [NSString stringWithFormat:@"%ld", PyInt_AsLong(pResult)];
    } else {
        NSDictionary *paramsDic = @{@"success": @"yes", @"msg": @"Python 函数 return 值获取失败"};
        NSError *dataError = nil;
        NSData *data = [NSJSONSerialization dataWithJSONObject:paramsDic options:NSJSONWritingPrettyPrinted error:&dataError];
        NSString *paramsStr = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
        finalize(pModule ,pFunc ,pDict ,pValue, pResult);
        return paramsStr;
    }
    
}

void finalize(PyObject *pModule, PyObject *pFunc, PyObject *pDict, PyObject *pValue, PyObject *pResult) {
    PyErr_Print();
    //释放对象
    if (Py_IsInitialized()) {
        Py_Finalize();
    }
}

@end

5:在 ViewController 中调用


1597053042535.jpg
GoogleTranslate *translate = [[GoogleTranslate alloc] init];
    NSString *res = [translate pyCallWithModule:"googleT" funcKey:"lgf_translate" Args:"fffffff"];
    NSLog(@"%@", res);

6: 输出:


1597053102385.jpg

这只是一个小模型,python 的开源库有很多好的模块,以后也可以辅助 xcode 项目,是不是很方便



喜欢的朋友记得点赞、收藏、关注哦!!!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/920161.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

蓝桥杯每日真题 - 第16天

题目&#xff1a;&#xff08;卡牌&#xff09; 题目描述&#xff08;13届 C&C B组C题&#xff09; 解题思路&#xff1a; 题目分析&#xff1a; 有 n 种卡牌&#xff0c;每种卡牌的现有数量为 a[i]&#xff0c;所需的最大数量为 b[i]&#xff0c;还有 m 张空白卡牌。 每…

计算机网络——路由选择算法

路由算法 路由的计算都是以子网为单位计算的——找到从原子网到目标子网的路径 链路状态算法 序号——&#xff08;源路由器&#xff0c;序号&#xff09;——如果发现这个序号重复或者老了——就不扩散 先测量——再泛洪获得路由 路由转发情况 若S——>W是21则不更改——…

Android - Pixel 6a 手机OS 由 Android 15 降级到 Android 14 操作记录

Pixel 6a 手机由 Android 14 升级到 Android 15了&#xff0c;但是由于一些原因又想降级回 Android 14&#xff0c; 能降吗&#xff1f;该怎么降级呢&#xff1f;本篇文章来记述实际操作过程&#xff0c;希望能给想做相同操作的人一些帮助。 答案当然是能降&#xff0c;而且我…

SpringBoot+React养老院管理系统 附带详细运行指导视频

文章目录 一、项目演示二、项目介绍三、运行截图四、主要代码1.入住合同文件上传2.添加和修改套餐的代码3.查看入住记录代码 一、项目演示 项目演示地址&#xff1a; 视频地址 二、项目介绍 项目描述&#xff1a;这是一个基于SpringBootReact框架开发的养老院管理系统。首先…

Ubuntu安装ollama,并运行ollama和通义千问,使用gradio做界面

Ubuntu安装ollama&#xff0c;并运行ollama和通义千问 安装ollama方式一&#xff1a;方式二 下载安装模型运行大模型运行ollama服务前端的实现python环境安装修改pip国内源前端页面搭建测试前后端联通设计完整的ui 安装ollama 方式一&#xff1a; 访问网站连接&#xff0c;选…

【微软:多模态基础模型】(3)视觉生成

欢迎关注[【youcans的AGI学习笔记】](https://blog.csdn.net/youcans/category_12244543.html&#xff09;原创作品 【微软&#xff1a;多模态基础模型】&#xff08;1&#xff09;从专家到通用助手 【微软&#xff1a;多模态基础模型】&#xff08;2&#xff09;视觉理解 【微…

前端研发高德地图,如何根据经纬度获取地点名称和两点之间的距离?

地理编码与逆地理编码 引入插件&#xff0c;此示例采用异步引入&#xff0c;更多引入方式 https://lbs.amap.com/api/javascript-api-v2/guide/abc/plugins AMap.plugin("AMap.Geocoder", function () {var geocoder new AMap.Geocoder({city: "010", /…

Linux上使用SELinux保护网络服务

前言 SELinux&#xff08;Security-Enhanced Linux&#xff09;是一种安全模块&#xff0c;用于增强基于 Linux 的操作系统的安全性。 它通过强制访问控制&#xff08;MAC&#xff09;机制来限制进程和用户对系统资源的访问权限&#xff0c;从而防止未经授权的操作。 在 SELin…

【Linux】僵尸进程、进程状态简介

本文内容均来自个人笔记并重新梳理&#xff0c;如有错误欢迎指正&#xff01; 如果对您有帮助&#xff0c;烦请点赞、关注、转发、订阅专栏&#xff01; 专栏订阅入口 | 精选文章 | Kubernetes | Docker | Linux | 羊毛资源 | 工具推荐 | 往期精彩文章 【Docker】&#xff08;全…

uniapp 选择 省市区 省市 以及 回显

从gitee仓库可以拿到demo 以及 json省市区 文件 // 这是组件部分 <template><uni-popup ref"popup" type"bottom"><view class"popup"><view class"picker-btn"><view class"left" click"…

Unity Dots下的动画合批工具:GPU ECS Animation Baker

书接上文&#xff0c;为了实现大批量物体的生成&#xff0c;我们准备使用Unity最新的dots系统&#xff0c;在该系统下找到了动画解决方案&#xff1a;GPU ECS Animation Baker。 导入的同时&#xff0c;也需要导入以下两个插件&#xff0c;否则会提示报错&#xff1a; PS&…

windows上部署flask程序

文章目录 前言一、准备工作二、配置 Gunicorn 或 uWSGI1.安装 Waitress2.修改启动文件来使用 Waitress 启动 Flask 应用3.配置反向代理&#xff08;可选&#xff09;4.启动程序访问 三.Flask 程序在 Windows 启动时自动启动1.使用 nssm&#xff08;Non-Sucking Service Manager…

共享单车管理系统项目学习实战

前言 Spring Boot Vue前后端分离 前端&#xff1a;Vue&#xff08;CDN&#xff09; Element axios(前后端交互) BaiDuMap ECharts(图表展示) 后端&#xff1a;Spring Boot Spring MVC(Web) MyBatis Plus(数据库) 数据库:MySQL 验证码请求

python中Pandas操作excel补全内容

补全ID、InStore、Date import random from datetime import datetime, timedeltaimport pandas as pdfile_path r"C:\Users\xb\Desktop\Books_1.xlsx" books pd.read_excel(iofile_path, skiprows3, usecols"C:F", dtype{"ID": str, "I…

40分钟学 Go 语言高并发:Goroutine基础与原理

Day 03 - goroutine基础与原理 1. goroutine创建和调度 1.1 goroutine基本特性 特性说明轻量级初始栈大小仅2KB&#xff0c;可动态增长调度方式协作式调度&#xff0c;由Go运行时管理创建成本创建成本很低&#xff0c;可同时运行数十万个通信方式通过channel进行通信&#x…

Python学习------第十天

数据容器-----元组 定义格式&#xff0c;特点&#xff0c;相关操作 元组一旦定义&#xff0c;就无法修改 元组内只有一个数据&#xff0c;后面必须加逗号 """ #元组 (1,"hello",True) #定义元组 t1 (1,"hello") t2 () t3 tuple() prin…

nwjs崩溃复现、 nwjs-控制台手动操纵、nwjs崩溃调用栈解码、剪切板例子中、nwjs混合模式、xdotool显示nwjs所有进程窗口列表

-1. nwjs在低版本ubuntu运行情况 ubuntu16.04运行nw-v0.93或0.89报错找不到NSS_3.30、GLIBC_2.25 uname -a #Linux Asus 4.15.0-112-generic #113~16.04.1-Ubuntu SMP Fri Jul 10 04:37:08 UTC 2020 x86_64 x86_64 x86_64 GNU/Linux cat /etc/issue #Ubuntu 16.04.7 LTS \n \l…

在自动驾驶进行大数据量因果推理实验时,如何减少无用功,提高实验效率?

在对实验结果做反事实推理时&#xff0c;通常需要对数据进行多次循环&#xff0c;然后对多次循环的结果进行处理&#xff0c;如果只在最后结果结束时&#xff0c;再进行处理&#xff0c;可能会由于反事实过程中某个参数设置错误&#xff0c;导致整个反事实实验出现错误&#xf…

DAY1 网络编程(TCP客户端服务器)

作业&#xff1a; TCP客户端服务器。 server服务器代码&#xff1a; #include <myhead.h> #define IP "192.168.110.52" #define PORT 8886 #define BACKLOG 20 int main(int argc, const char *argv[]) {int oldfdsocket(AF_INET,SOCK_STREAM,0);//IPV4通信…

Kafka怎么发送JAVA对象并在消费者端解析出JAVA对象--示例

1、在pom.xml中加入依赖 <dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-stream-kafka</artifactId><version>3.1.6</version></dependency> 2、配置application.yml 加入Kafk…