2010-12-04 38 views
3

我正在實施一個ObjC協議作爲PyObjC類的混合。PyObjC和返回'出'參數(即NSError **)

該協議定義了「out」參數。

我無法找到任何有關如何實現ObjC協議定義這個行爲的Python類的好文檔。

我找到了這個mailing list thread,但在那裏的建議不起作用。他們說要返回一個Python列表,並將方法的返回值作爲第一項,將out參數作爲第二項。

我試過這個,所有我從ObjC(<type 'exceptions.ValueError'>: depythonifying 'char', got 'tuple')調用時是一個例外。

看來PyObjC在depythonifying方法參數時嚴格遵守ObjC協議,這很好,但它並不幫助我試圖修改out參數。

這是ObjC協議:

#import <Foundation/Foundation.h> 

@protocol TestProtocol <NSObject> 

- (BOOL)testMethod:(NSError **)error; 

@end 

這是Python類實現此協議:

from Foundation import * 
import objc 

NSObject = objc.lookUpClass("NSObject") 
TestProtocol = objc.protocolNamed("TestProtocol") 

class TestClass(NSObject, TestProtocol): 

    def testMethod_(self, error): 
     return True, None 

問題:我如何返回一個Python ObjC out參數?

回答

3

這個問題的時候,所以我不知道你是否現在整理出來,但是你有沒有回答了這個問題,並且我很早就從Obj-C發佈Python到Python。有幾件事你絕對應該嘗試/研究:

首先也是最簡單的是:當你在Objective-C中使用Python實現該存根時,必須指定(NSError **)out參數:

@interface MyObject : NSObject 
- (BOOL)testMethod:(out NSError **)error; 
@end 

我用這個成功調用在Python定製的OBJ-C方法。我相信Python方面不會獲得正確的元數據。

還有一個signature修飾器添加到您的Python方法定義中。您可以指定其中一個參數是sig中的out參數。這PyObjC doc給出的細節。

@objc.signature('@@:io^@') 

另一件事是(你可能現在想通了這一點你自己),如果你不想做的Objective-C的存根,您可以生成自己的元數據和將一個.bridgesupport文件粘貼到您的項目中。我不確定的唯一一件事(大事!)是如何確保這個文件實際上被讀取。元數據本身非常易於編寫 - Apple提供了一個名爲gen_bridge_metadata的命令行實用程序,您可以手動完成此操作(查看/System/Library/Frameworks/Python.framework/Versions/2.6/Extras/lib/python /PyObjC/AppKit/PyObjC.bridgesupport)。 Theres a man page for the utility,and man 5 BridgeSupport also informative。您應該閱讀的另一個Apple文檔是:Generating Framework Metadata

爲未來的讀者UPDATE:我已經找到了功能objc.registerMetaDataForSelectorobjc.parseBridgeSupport,這兩者允許你添加元數據的方法,即使用Python的類型的字典(原函數),或在BridgeSupport描述的XML格式手冊頁(後者)。使用registerMetaData...的例子可以在pyobjc源文件中找到:pyobjc/pyobjc-core/PyObjCTest/test_metadata*,我通過這個pyobjc-dev郵件列表thread發現了這個例子。

2

我已經試過這和所有我得到ObjC 打電話時是 異常(: depythonifying「炭」,有「元組」)。

PyObjC通常將錯誤作爲元組的第二個元素傳回。

喜歡的東西:

response, error = object.someMethod_error_(foo) # leave off the error 
if not response: 
    # process error 

看到你更新...

你要麼不得不潛入元橋,並找出如何在運行時應用一些元數據您的實施,使其工作。

或者,可能更容易,是從編譯的Objective-C存根類繼承而來。

I.e.試試這個:

@interface AbstractFoo : NSObject 
@end 

@implementation AbstractFoo 
- (BOOL) myMethod: (int) arg error: (NSError **) anError; 
{ 
    return YES; 
} 
@end 

然後,你應該能夠從Python側繼承AbstractFoo可能「只是工作」。

也許吧。

(對不起 - 已經有一段時間我一直在這個深藏在PyObjC)

+0

「PyObjC通常會將錯誤作爲元組的第二個元素傳回。」 是的,這就是我的Python方法(testMethod_)正在做的。但是PyObjC在退回ObjC土地時不遵守這條規則,隨後拋出異常。 我看到的互聯網上所有答案的混淆,似乎源於從Python調用ObjC與從ObjC調用Python之間的區別。 我對後者感興趣。 一個行爲不像另一個。 – firstresponder 2010-12-05 01:04:13