Forum Archive

how can i access dispatch_get_main_queue

ryubai

i'm a newer for pythonista and love it so much.and i have a question to ask:
how can i access dispatch_get_main_queue function in cdll? it always tell me symbol not found.

i try to access like this:
print(c.dispatch_get_main_queue).
in this way it's okay for dispatch_get_current_queue and dispatch_get_global_queue

ccc

print(c.dispatch_get_main_queue()) ?

ryubai

thanks for reply ,but still show "symbol not found"

dgelessus

dispatch_get_main_queue is not a normal C function, so you can't access it normally via ctypes/objc_util. Instead, you need to reproduce dispatch_get_main_queue's functionality in Python using some custom code:

from ctypes import Structure, byref, cast, c_void_p
from objc_util import ObjCInstance, c

class struct_dispatch_queue_s(Structure):
    pass

_dispatch_main_q = struct_dispatch_queue_s.in_dll(c, "_dispatch_main_q")

def dispatch_get_main_queue():
    return ObjCInstance(cast(byref(_dispatch_main_q), c_void_p))

You don't need to understand what this code does exactly - you can just copy-paste it into your code and use dispatch_get_main_queue() like you would normally.

(If anyone is interested in the exact details of what the above code does and where it comes from, see this page. The original C code is very complex, so you need to be familiar with both ctypes and the C preprocessor to understand all the translation steps. But again, you don't have to understand all of this - you can just copy-paste and use the finished Python code.)

ryubai

it works,thank you very much! ^_^

ryubai

@dgelessus
one more step,i want to use dispatch_async,but it didn’t wok.
could u give me a hand? thanks in advance.

dispatch_async=c.dispatch_async
dispatch_async.restype=c_void_p
dispatch_async.argtypes=[c_void_p,c_void_p]

def nike():
print('ok')
dispatch_async(dispatch_get_main_queue(),nike)

dgelessus

The second argument of dispatch_async needs to be a block object. You can't pass in a normal Python function, because ctypes won't know how to convert it. Instead, you have to create the block object manually:

def block_code(_self):
    print("ok")
block = ObjCBlock(block_code, None, [c_void_p])
dispatch_async(dispatch_get_main_queue(), byref(block._as_parameter_))

For more details about how ObjCBlock works, you can look at the ObjCBlock section of the objc_util documentation.

By the way, dispatch_async doesn't return anything, so you should set its restype to None and not c_void_p. (If you use c_void_p it will probably still work, but the return value won't be anything useful.)

ryubai

@dgelessus
got it! learn more from you.thanks

ryubai

@dgelessus

sir,I read your latest replies in the forum and interested in rubicon.objc you mentioned.I have installed it by pip install rubicon.objc with stash but it doesn’t work.

when I run
from rubicon.objc import NSInteger, NSObject, ObjCProtocol, objc_method

it showed a error, could you give me a help? thanks so much.

Traceback (most recent call last):
File "/private/var/mobile/Containers/Shared/AppGroup/02422888-CC52-45FC-BB53-72013D3F4AFA/Pythonista3/Documents/t_rubicon.py", line 1, in
from rubicon.objc import NSInteger, NSObject, ObjCProtocol, objc_method
File "/private/var/mobile/Containers/Shared/AppGroup/02422888-CC52-45FC-BB53-72013D3F4AFA/Pythonista3/Documents/site-packages-3/rubicon/objc/init.py", line 15, in
from . import runtime # noqa: F401
File "/private/var/mobile/Containers/Shared/AppGroup/02422888-CC52-45FC-BB53-72013D3F4AFA/Pythonista3/Documents/site-packages-3/rubicon/objc/runtime.py", line 2, in
from ctypes import (
File "/var/containers/Bundle/Application/789BA705-9D92-409A-8DF3-9D0806F2BD5B/Pythonista3.app/Frameworks/Py3Kit.framework/pylib/ctypes/util.py", line 72, in
from ctypes.macholib.dyld import dyld_find as _dyld_find
ModuleNotFoundError: No module named 'ctypes.macholib'

dgelessus

If I'm reading the error message correctly, rubicon.objc is installed properly. The error about ctypes.util/ctypes.macholib is a known issue in Pythonista: https://github.com/omz/Pythonista-Issues/issues/311

Sadly it hasn't been fixed yet, but there is a workaround - you can copy the missing files from the CPython source code. See this comment on the issue for instructions: https://github.com/omz/Pythonista-Issues/issues/311#issuecomment-398715503

Blanc7a

I have not been able to find an example of how to run native a sync code and curious with regards to iOS specifically, can something like this be done in N?

ryubai

@dgelessus

great!it has worked under your kind guidance!
thank you very very much!

Alderliesten

This cryptic looking statement will throw something to a background thread while the main thread can deal with other functions. This is especially useful if a method would take a long time dgcustomerfirst

dahliaivy006

this helped me to find the solution DGCustomerFirst