[Python] How do I use the various obs_enum_*() functions?

DarkMorford

New Member
I'm trying to write a scene switcher/controller script in Python that would integrate with my overlay control panel. Unfortunately, I'm stuck right out of the gate because I can't figure out the syntax for calling obs_enum_transition_types() or any of its function family, specifically passing the second (output) argument. Here's some sample code to illustrate:
Code:
import obspython as obs
from ctypes import byref, c_char_p

def script_load(settings):
    typename = c_char_p()
    valid = obs.obs_enum_transition_types(0, byref(typename))
    if (valid):
        print(typename)
And the error I get is TypeError: in method 'obs_enum_transition_types', argument 2 of type 'char const **'. From my limited knowledge of ctypes, I'm pretty sure the combination of c_char_p and byref() is getting me the double-pointer, but I can't figure out how to get the const qualifier in there. Has anyone been successful calling these functions from Python, or are the bindings just busted?

EDIT: There's a bug on Mantis that doesn't cover this exact issue, but does touch on working with double-pointer functions in general. See #1244.
 

Mohamed RACHID

New Member
Hi!
Even though I have very little experience with ctypes either, I'll provide my ideas anyway.
In your example, typename is a c_char_p instance, corresponding to a null-terminated char*.
Calling byref(typename) returns the address of typename, which seems correct in the first place.
My guess is that it actually corresponds to the char* const* qualified type, because it is tied to typename. Do not forget that it is a reference.

Here is how I would try:
Python:
import obspython
from ctypes import POINTER, c_char_p

def script_load(settings):
    typename = None
    typename_ptr = POINTER(c_char_p)()  # new NULL pointer to a null-terminated char*, probably a char**
    if obspython.obs_enum_transition_types(0, typename_ptr):
        typename = typename_ptr[0].decode("utf-8")  # converting a bytes-like object into an str
    print("typename =", typename)
I have not tested this code.
 

upgradeQ

Member
Try loading obs library itself:

Python:
import obspython as obs
from ctypes import POINTER, c_char_p, CDLL, byref

obsapi = CDLL("obs")


def f():
    typename = c_char_p()
    if obsapi.obs_enum_transition_types(0, byref(typename)):
        print(dir(typename))
        typename = typename.value

    print("typename =", typename)


def on_load(event):
    if event == obs.OBS_FRONTEND_EVENT_FINISHED_LOADING:
        f()


def script_load(settings):
    obs.obs_frontend_add_event_callback(on_load)
Output : typename = b'move_transition'
Also note: ctypes and cffi throw import error on linux, see this issue
 
Top