如何将python嵌入到Objective-C OS X应用程序的插件? [英] How to embed python in an Objective-C OS X application for plugins?

查看:147
本文介绍了如何将python嵌入到Objective-C OS X应用程序的插件?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想在一个新的OS X应用程序中使用python插件脚本。我正在寻找卸载一些程序逻辑到python为容易,即时修改。我开始看看大内氏牧场教程。这似乎工作,但它建议链接Python的旧方法。看起来,自从Xcode 5,我们应该使用此Mac开发人员安装python图书馆技术说明。然而,这个过程似乎创建一个链接的python实例,而不是嵌入的。我已尝试遵循此问题的回答中的指南,但它似乎崩溃。



所以我的问题是这是:目前最好的做法是构建python用作一个Objective C Mac OS X应用程序的插件运行时?如何确保它与应用程序捆绑在一起,并且可以在构建最终的Objective C应用程序之前安装任何其他可能需要的库?



首先,下载python的源代码版本,您可以从官方网站。提取归档某处。我使用Python 3.4.2。



创建一个构建目录,您将使用这个开发版本的python版本。整个目录应该没有空格,以确保bash正确地解释了she-bang(#!)行。我使用 /Users/myaccount/development/python/devbuild/python3.4.2



进入解压缩的Python目录并运行以下命令:

  ./ configure --prefix =/ Users / myaccount / development / python / devbuild / python3.4.2
make
make install

这将在开发构建目录中安装python。设置Python路径以使用正确的目录:

  export PYTHONPATH =/ Users / myaccount / development / python / devbuild / python3 .4.2 / lib / python3.4 / site-packages /

进入python bin目录 /Users/myaccount/development/python/devbuild/python3.4.2/bin )并使用 pip3 安装任何您需要的模块。 $ PYTHONPATH 设置将确保模块安装到正确的 site-packages 目录中。



找到PyObjC存储库的一个方便的家,并克隆它。然后检出最新版本标签并安装,确保您的 $ PYTHONPATH 仍然正确:

  hg clone https://bitbucket.org/ronaldoussoren/pyobjc 
cd pyobjc
hg标签
hg checkout [标签列表中最新版本的标识]
/Users/myaccount/development/python/devbuild/python3.4.2/bin/python3 ./install.py

每当你需要更新python模块时,只要确保使用正确的python bin和 $ PYTHONPATH


$



拖动 / Users / myaccount / development / python / devbuild / python3现在添加python到Xcode项目.4.2 目录导入Xcode项目,将其设置为不根据需要复制项目,并创建文件夹引用。



添加 /Users/myaccount/development/python/devbuild/python3.4.2/include/python3.4m 添加到标题搜索路径设置Xcode项目的构建设置



拖动`/ Users / myaccount / development /目录下的文件夹, python / devbuild / python3.4.2 / lib / libpython3.4m.a库放入Xcode项目中,将其设置为引用而不复制。



现在可以对 Big Nerd Ranch脚本教程存储库中的代码进行一些修改。



插件管理器代码将需要一个NSString扩展来使用 wchar_t 字符串,Python API似乎这么喜欢:

  @interface NSString(WcharEncodedString)

- (wchar_t *)getWideString;

@end

@implementation NSString(WcharEncodedString)

- (wchar_t *)getWideString {
const char * tmp = cStringUsingEncoding:NSUTF8StringEncoding];
unsigned long buflen = strlen(tmp)+ 1;
wchar_t * buffer = malloc(buflen * sizeof(wchar_t));
mbstowcs(buffer,tmp,buflen);
return buffer;
}

@end

如下:

  #includePython.h

下面的代码需要在调用之前运行Py_Initialize(),以便设置正确的python可执行文件PYTHONPATH ,和Zorg在另一个问题上建议的PYTHONHOME。

  NSString * executablePath = [[NSBundle mainBundle] pathForResource:@python3 .4ofType:nil inDirectory:@python3.4.2 / bin]; 
Py_SetProgramName([executablePath getWideString]);

NSString * pythonDirectory = [[NSBundle mainBundle] pathForResource:@python3.4ofType:nil inDirectory:@python3.4.2 / lib];
Py_SetPath([pythonDirectory getWideString]);
Py_SetPythonHome([pythonDirectory getWideString]);

最后,python路径需要在 PluginExecutor.py 文件,以包括高级别 lib 路径的各个子目录。将以下代码添加到Plugin Executor文件的顶部:

  import sys 
从os import walk
path = sys.path.copy()
在路径中的p:
用于root,dirs,walk(p)中的文件:
如果p不是root:
sys .path.append(root)



如果事情开始崩溃,我会发布更新似乎是现在的工作解决方案。


I'm trying to use python in a new OS X application for plugin scripting. I'm looking to offload some of the program logic to python for easy, on-the-fly modification. I had started by looking at the Big Nerd Ranch tutorial. That seemed to work, but it suggested an older method of linking Python. It appears that since Xcode 5, we are supposed to install python using this Mac Developer Library Tech Note. This process, however, seems to create a linked python instance, not an embedded one. I've tried following the guidelines in the answer to this question but it seems to break down.

So my question is this: what are the current best practices for building python for use as a plugin runtime in an Objective C Mac OS X app? How does one go about making sure that it is bundled with the application, and that it is possible to install any additional libraries that one might want before the final Objective C app is built?

解决方案

I've come up with a method that seems to work fairly well.

First, download source of the python version you want to use from the official website. Extract the archive somewhere. I'm using Python 3.4.2. Adjust the commands on your system for the specific version you're using.

Create a build directory that you will use for this development python version. The entire directory should have no spaces in it to make sure that bash interprets the she-bang (#!) lines correctly. I used /Users/myaccount/development/python/devbuild/python3.4.2.

Go into the extracted Python directory and run the following commands:

./configure --prefix="/Users/myaccount/development/python/devbuild/python3.4.2"
make
make install

This will install python in that development build directory. Setup the Python path to use the correct directory:

export PYTHONPATH="/Users/myaccount/development/python/devbuild/python3.4.2/lib/python3.4/site-packages/"

Go into the python bin directory (/Users/myaccount/development/python/devbuild/python3.4.2/bin) and use the pip3 there to install any modules that you need. The $PYTHONPATH setting will ensure that the modules get installed into the correct site-packages directory.

Find a handy home for the PyObjC repository and clone it there. Then checkout the latest version tag and install it, making sure that your $PYTHONPATH is still correct:

hg clone https://bitbucket.org/ronaldoussoren/pyobjc
cd pyobjc
hg tags
hg checkout [the id of the latest version from the tag list]
/Users/myaccount/development/python/devbuild/python3.4.2/bin/python3 ./install.py

Whenever you need to update the python modules, just make sure to use the correct python bin and $PYTHONPATH.

Now to add python to an Xcode project.

Drag the /Users/myaccount/development/python/devbuild/python3.4.2 directory into the Xcode project, setting it to not copy items as necessary, and to create a folder reference.

Add /Users/myaccount/development/python/devbuild/python3.4.2/include/python3.4m to the Header Search Paths setting in the Xcode project's Build Settings. Not sure if there's a way to do this as a generalized step to just search the folder referenced directory we had just added.

Drag the `/Users/myaccount/development/python/devbuild/python3.4.2/lib/libpython3.4m.a library into the Xcode project, setting it to be added as a reference without copying as well.

The code from the Big Nerd Ranch scripting tutorial repository can now be used with a few modifications.

The Plugin Manager code will need an NSString extension to work with the wchar_t strings that the Python API seems to like so much:

@interface NSString (WcharEncodedString)

- (wchar_t*) getWideString;

@end

@implementation NSString (WcharEncodedString)

- (wchar_t*) getWideString {
    const char* tmp = [self cStringUsingEncoding:NSUTF8StringEncoding];
    unsigned long buflen = strlen(tmp) + 1;
    wchar_t* buffer = malloc(buflen * sizeof(wchar_t));
    mbstowcs(buffer, tmp, buflen);
    return buffer;
}

@end

The Python header should be included as follows:

#include "Python.h"

The following code needs to be run before Py_Initialize() is called in order to set up the correct python executable, PYTHONPATH, and PYTHONHOME as suggested by Zorg on that other question.

NSString* executablePath = [[NSBundle mainBundle] pathForResource:@"python3.4" ofType:nil inDirectory:@"python3.4.2/bin"];
Py_SetProgramName([executablePath getWideString]);

NSString* pythonDirectory = [[NSBundle mainBundle] pathForResource:@"python3.4" ofType:nil inDirectory:@"python3.4.2/lib"];
Py_SetPath([pythonDirectory getWideString]);
Py_SetPythonHome([pythonDirectory getWideString]);

Finally, the python path needs to be expanded in the PluginExecutor.py file to include the various subdirectories of the high level lib path. Add the following code to the top of the Plugin Executor file:

import sys
from os import walk
path = sys.path.copy()
for p in path:
    for root,dirs,files in walk(p):
        if p is not root:
            sys.path.append(root)

I'll post updates if things start to break down, but this seems a working solution for now.

这篇关于如何将python嵌入到Objective-C OS X应用程序的插件?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆