-
Notifications
You must be signed in to change notification settings - Fork 1
Plugin Wrapper | Python
Below are the public facing plugin wrapper features for the python wrapper. To see how python plugins are implemented see Plugin Implementation | Python.
Below are basic features which only require a working knowledge of python.
The python wrapper uses ctypes to communicate with other plugins. So any MADZ base type interfacing with c or other plugins will be done through ctypes. All top level variables must be declared in the __init__.py file with the names described in the plugin description, the __init__.py file is also the file that will be run as part of the plugin's init code.
The start of the __init__.py, and any modules that want access to the available madz information should start with the following import:
import madz# Get the 'foo' variable from this plugin
result = madz.self.foo
# Get the 't_Foo' type from this plugin
result = madz.types.t_Foo# Get the variable 'foo' from a depends plugin 'example.plugin':
result = madz.depends["example.plugin"].foo
# Get the variable 'foo' from an imports plugin 'example.plugin':
result = madz.imports["example.plugin"].foo
# Get the ctype object representing the type 't_Foo' from an depends plugin 'example.plugin':
result = madz.types.depends["example.plugin"].t_Foo
# Get the ctype object representing the type 't_Foo' from an imports plugin 'example.plugin':
result = madz.types.imports["example.plugin"].t_Foo# Call the function 'foo' from the depends plugin 'example.plugin'
# This can raise the ctypes exceptions involved with calling an external function.
result = madz.depends["example.plugin"].foo()# A function which takes a t_Struct_A and returns a t_Struct_B
# Both structs have a single integer argument called 'x'
def foo(struct_a):
# Create the struct B
struct_b = madz.types.t_Struct_B()
# Assign the variable:
struct_b.x = struct_a.x
# Return the struct:
return struct_b# Global malloc space
last_foo = None
# A function which takes a t_Struct_A* and returns a t_Struct_B*
# Both structs have a single integer argument called 'x'
def foo(struct_a):
# Create the struct B
struct_b = madz.ctypes.POINTER(madz.types.t_Struct_B())
# Assign the variable:
struct_b.contents.x = struct_a.contents.x
# Prevent struct_b from being garbage collected:
# Only works for the last foo call, once foo is called again
# the old value in here will be garbage collected; consider using
# a dictionary instead.
last_foo = struct_b
# Return the struct:
return struct_bMADZ provides a place to temporarily store values:
# Prevents gc on the given object.
madz.prevent_gc["some_application_unique_key"] = an_object
# The preferred ways to generate a key:
madz.prevent_gc[(__file__, "file_unique_key")] = an_object
madz.prevent_gc[(self.__class__, "class_unique_key")] = an_object
madz.prevent_gc[(self, "instance_unique_key")] = an_object
# Remove an entry:
del madz.prevent_gc["original_name"]
# Replace an entry, garbage collecting the old one:
madz.prevent_gc["original_name"] = an_objectBelow are intermediate features, which require a strong working knowledge of how python, and other languages, operate.
The python wrapper provides access to malloc and free. This is useful when a plugin function is only responsible for allocating or deallocating an object using the cstdlib approach. (Generally plugins should be designed so that the plugin in question is responsible for managing the life time of it's objects.)
# Returns a ctypes pointer to an object of type t_Foo
foo = madz.mem.malloc(madz.types.t_Foo)
# Frees the memory at a ctypes pointer
madz.mem.free(foo)
# Raw ctypes function access:
malloc, free = (madz.cstdlib.malloc, madz.cstdlib.free)