PyObjC 和 method_exchangeImplementations:崩溃。正确用法?

发布于 2024-12-04 08:05:41 字数 1654 浏览 1 评论 0原文

我正在使用 PyObjC。 PyObjC 不提供 method_exchangeImplementations 接口,因此我尝试通过 ctypes 使用该函数。我试图从某些窗口控制器类覆盖 windowShouldClose:

我的代码:

import objc
BrowserWindowController = objc.lookUpClass("BrowserWindowController")

class BrowserWindowController(objc.Category(BrowserWindowController)):
    def myWindowShouldClose_(self, sender):
        print "myWindowShouldClose", self, sender
        return self.myWindowShouldClose_(sender)

from ctypes import *
capi = pythonapi

# id objc_getClass(const char *name)
capi.objc_getClass.restype = c_void_p
capi.objc_getClass.argtypes = [c_char_p]

# SEL sel_registerName(const char *str)
capi.sel_registerName.restype = c_void_p
capi.sel_registerName.argtypes = [c_char_p]

def capi_get_selector(name):
    return c_void_p(capi.sel_registerName(name))

# Method class_getInstanceMethod(Class aClass, SEL aSelector)
# Will also search superclass for implementations.
capi.class_getInstanceMethod.restype = c_void_p
capi.class_getInstanceMethod.argtypes = [c_void_p, c_void_p]

# void method_exchangeImplementations(Method m1, Method m2)
capi.method_exchangeImplementations.restype = None
capi.method_exchangeImplementations.argtypes = [c_void_p, c_void_p]

def hook_into_close():
    clazz = capi.objc_getClass("BrowserWindowController")
    origClose = capi.class_getInstanceMethod(clazz, capi_get_selector("windowShouldClose:"))
    newClose = capi.class_getInstanceMethod(clazz, capi_get_selector("myWindowShouldClose:"))
    capi.method_exchangeImplementations(origClose, newClose)

这会崩溃。 [NSWindow _close] 中有一些奇怪的回溯。

代码基本正确吗?

问题是什么?

I'm using PyObjC. PyObjC doesn't provide an interface to method_exchangeImplementations so I was trying to use the function via ctypes. I was trying to overwrite windowShouldClose: from some window controller class.

My code:

import objc
BrowserWindowController = objc.lookUpClass("BrowserWindowController")

class BrowserWindowController(objc.Category(BrowserWindowController)):
    def myWindowShouldClose_(self, sender):
        print "myWindowShouldClose", self, sender
        return self.myWindowShouldClose_(sender)

from ctypes import *
capi = pythonapi

# id objc_getClass(const char *name)
capi.objc_getClass.restype = c_void_p
capi.objc_getClass.argtypes = [c_char_p]

# SEL sel_registerName(const char *str)
capi.sel_registerName.restype = c_void_p
capi.sel_registerName.argtypes = [c_char_p]

def capi_get_selector(name):
    return c_void_p(capi.sel_registerName(name))

# Method class_getInstanceMethod(Class aClass, SEL aSelector)
# Will also search superclass for implementations.
capi.class_getInstanceMethod.restype = c_void_p
capi.class_getInstanceMethod.argtypes = [c_void_p, c_void_p]

# void method_exchangeImplementations(Method m1, Method m2)
capi.method_exchangeImplementations.restype = None
capi.method_exchangeImplementations.argtypes = [c_void_p, c_void_p]

def hook_into_close():
    clazz = capi.objc_getClass("BrowserWindowController")
    origClose = capi.class_getInstanceMethod(clazz, capi_get_selector("windowShouldClose:"))
    newClose = capi.class_getInstanceMethod(clazz, capi_get_selector("myWindowShouldClose:"))
    capi.method_exchangeImplementations(origClose, newClose)

This crashes. With some strange backtrace in [NSWindow _close].

Is the code basically right?

What is the problem?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

画离情绘悲伤 2024-12-11 08:05:41

啊,当我在 def myWindowShouldClose_ 前面添加 @objc.signature(BrowserWindowController.windowWillClose_.signature) 时,它不再崩溃了。

所以这只是错误/不匹配的签名。

Ah, when I add @objc.signature(BrowserWindowController.windowWillClose_.signature) infront of def myWindowShouldClose_, it doesn't crash anymore.

So it just was the wrong/non-matching signature.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文