alephOneTutorial

[ Start > PikeDevel > C Modules > alephOneTutorial ] [ Edit this Page | Show Page Versions | Show Raw Source ]


PIKE C MODULE HOW-TO

If you are attempting to write a module for Pike in C it is likely that you are trying to interface Pike to some C library. Although you could possibly write a Pike module in C for performance reasons you are better off writing it in Pike itself. In this document we will only cover enough of Pike's C interfaces to allow you to write glue code to interface a C library into a Pike module.

This text assume you are familiar with both C and Pike. If you are not familiar with Pike read the Pike Manual. The information on this how-to is based on Pike 0.6.

Background


A little background before we begin. A Pike program is a collection of functions (executable code) and a description of some data storage. A Pike program is similar to a C++ class. A Pike program is a blueprint for a Pike object similar to how a C++ class is a blueprint for a C++ class instance.

A Pike object is a data type that allocates memory to store the variables described by a Pike program. A Pike object is similar to a C++ class instance. You create a Pike object by "cloning" a Pike program. When a Pike program is cloned the "create" function is called in the new Pike object, if it exists, to initialize it. You deallocate a Pike object by "destroying" it. When a Pike program is destroyed the "destroy" function is called in the Pike object, if it exists, to deinitialize it.

A Pike module is a software package that plugs into the Pike programming environment. They are composed of one or more Pike programs. If there is only one program the program name is the same as the module name. If the are more than one program in the module they are accessed using the "." operator (e.g. Foo.Bar).

Internals


All Pike data types are represented internally with an 'svalue' structure. The structure has three elements: type, subtype, and u. "type" determines the type of the data. Valid values are T_ARRAY, T_MAPPING, T_MULTISET, T_OBJECT, T_FUNCTION, T_PROGRAM, T_STRING, T_FLOAT, and T_INT. "u" is an union of the structures callable, array, mapping, multiset, object, program, pike_string, as well as the types INT32 *, INT_TYPE, and FLOAT_TYPE.

All Pike code shares a single stack which is accessible internally via the 'sp' global variable. The frame pointer is available as the 'fp' global variable.

To store private object data you should allocate storage for it using the add_storage() function. The storage is available via the frame pointer as fp->current_storage.

Mandatory Module Functions


void pike_module_init(void)

This functions is called by Pike to initialize the module. The function takes no arguments, and returns nothing. In it all functions (using add_function()), object variables, sub-programs, and private object storage (using add_storage()) should be added.

add_function(), add_storage() and other functions that manipulate a program works on the currently active new program. Before a module is initialized Pike creates a new program for it. So when pike_module_init() is called the active new program is the global module program. For example if you module is called "Foo" and the first thing you do in this function is call add_function() to add a function called "hello" the function would be added to the "Foo" program ("Foo.hello()").

If you wish to create sub-program within your module you need to call start_new_program(). This function pushes the active new program onto a stack and replaces the currently active new program with a new one. Any calls to add_function() or add_storage() will now operate on this new program.

When you are done building the sub-program you need to call end_class() to pop the parent program from the stack to replace the current active new program and to add your new program to the parent program.

If for some reason you need to obtain a handle to the program structure of the program you are adding you can instead of using end_class() call end_program() to pop the parent program from the stack to replace the current active new program and which returns a pointer to the program structure, and then call add_program_constant() to add your new program to the parent program.

If you want to have multiple programs within your module (e.g. Foo.Bar) you need to call start_new_program()

You can also set here callback functions to be called when your program is cloned or an object cloned is destructed via the set_init_callback() and set_exit_callback() functions.

void pike_module_exit(void)

This function is called by Pike when the module is no longer needed. This function should free any data structures allocated in the pike_module_init() function such as a program structure returned by end_program() (using free_program()).

Program/Object Functions


Module functions have a type definitions of:

void name( INT32 args )

'args' is the number of arguments the function received. You should always check the number of arguments to the function is what you expect (even when you except zero arguments).

Arguments are passed to the function on the Pike stack. You can access the arguments by using the global stack pointer "sp". For example the first argument is available as "sp[create -args]", the second argument as "sp[create 1-args]", the third as "sp[create 2-args]", etc.

The function is required to pop any arguments to it from the stack and to push its return value, if any, onto the stack.If the function fails to pop its arguments from the stack you will have a memory leak.

You can use the functions pop_stack() and pop_n_elems() to pop elements from the stack.

You can use the functions push_string(), push_int(), push_program(), push_mapping(), push_array(), push_multiset(), push_string(), push_object(), push_float(), push_constant_text(), ref_push_program(), ref_push_mapping(), ref_push_array(), ref_push_multiset(), ref_push_string(), ref_push_object(), and push_svalue() to push elements on the stack.

You register the module functions from the pike_module_init() function by calling add_function().

Initializing and De-Initializing Objects


When a new Pike object is created by cloning a Pike program the function "create" is called in the new object if it exists. If you need to initialize the object you can add this function to your programs and put any initialization code in it. You can also add a "destroy" function that will be called when the object is deallocated to deinitialize the object.

Header Files


File Description

array.h Array data type and functions.

struct array

The Pike array data type.

void free_array(struct array *a)

Deallocate a Pike array.

a Pointer to Pike array to deallocate.

void allocate_array(struct array *a)

Allocates an empty Pike array.

a Pointer to the allocated Pike array.

void array_index(struct svalue *s,struct array *v,INT32 index); void array_free_index(struct array *v,INT32 index); void array_set_index(struct array *v,INT32 index, struct svalue *s); struct array *array_insert(struct array *v,struct svalue *s,INT32 index); struct array *resize_array(struct array *a, INT32 size); struct array *array_shrink(struct array *v,INT32 size); struct array *array_remove(struct array *v,INT32 index); INT32 array_search(struct array *v, struct svalue *s,INT32 start); struct array *slice_array(struct array *v,INT32 start,INT32 end); struct array *copy_array(struct array *v); void sort_array_destructively(struct array *v); struct array *order_array(struct array *v, INT32 *order); INT32 * merge(struct array *a,struct array *b,INT32 opcode); struct array *subtract_arrays(struct array *a, struct array *b); struct array *and_arrays(struct array *a, struct array *b); struct array *aggregate_array(INT32 args); struct array *append_array(struct array *a, struct svalue *s); struct array *explode(struct pike_string *str, struct pike_string *del); struct pike_string *implode(struct array *a,struct pike_string *del); struct array *copy_array_recursively(struct array *a,struct processing *p); void apply_array(struct array *a, INT32 args); struct array *reverse_array(struct array *a); void array_replace(struct array *a, struct svalue *from, struct svalue *to); struct array *explode_array(struct array *a, struct array *b); struct array *implode_array(struct array *a, struct array *b);

backend.h Function to interact with the Pike backend.

struct callback *add_backend_callback(callback_func call, void *arg, callback_func free_func) void wake_up_backend(void); void init_backend(void); void set_read_callback(int fd,file_callback cb,void *data); void set_write_callback(int fd,file_callback cb,void *data); void set_read_oob_callback(int fd,file_callback cb,void *data); void set_write_oob_callback(int fd,file_callback cb,void *data); file_callback query_read_callback(int fd); file_callback query_write_callback(int fd); file_callback query_read_oob_callback(int fd); file_callback query_write_oob_callback(int fd); void *query_read_callback_data(int fd); void *query_write_callback_data(int fd); void *query_read_oob_callback_data(int fd); void *query_write_oob_callback_data(int fd); void do_debug(void); void backend(void); int write_to_stderr(char *a, INT32 len);

builtin_functions.h Pike's builtin functions.

void f_equal(INT32 args); void f_aggregate(INT32 args); void f_trace(INT32 args); void f_hash(INT32 args); void f_copy_value(INT32 args); void f_ctime(INT32 args); void f_lower_case(INT32 args); void f_upper_case(INT32 args); void f_random(INT32 args); void f_random_seed(INT32 args); void f_query_num_arg(INT32 args); void f_search(INT32 args); void f_backtrace(INT32 args); void f_add_constant(INT32 args); void f_combine_path(INT32 args); void f_function_object(INT32 args); void f_function_name(INT32 args); void f_zero_type(INT32 args); void f_string_to_unicode(INT32 args); void f_unicode_to_string(INT32 args); void f_string_to_utf8(INT32 args); void f_utf8_to_string(INT32 args); void f_all_constants(INT32 args); void f_allocate(INT32 args); void f_rusage(INT32 args); void f_this_object(INT32 args); void f_throw(INT32 args); void f_exit(INT32 args); void f__exit(INT32 args); void f_time(INT32 args); void f_crypt(INT32 args); void f_destruct(INT32 args); void f_indices(INT32 args); void f_values(INT32 args); void f_next_object(INT32 args); void f_object_program(INT32 args); void f_reverse(INT32 args); struct tupel; void f_replace(INT32 args); void f_compile(INT32 args); void f_mkmapping(INT32 args); void f_objectp(INT32 args); void f_functionp(INT32 args); void f_sleep(INT32 args); void f_gc(INT32 args); void f_programp(INT32 args); void f_sort(INT32 args); void f_rows(INT32 args); void f_column(INT32 args); void f__verify_internals(INT32 args); void f__debug(INT32 args); void f__compiler_trace(INT32 args); void f_gmtime(INT32 args); void f_localtime(INT32 args); void f_glob(INT32 args); void f_diff_compare_table(INT32 args); void f_diff_longest_sequence(INT32 args); void f_diff_dyn_longest_sequence(INT32 args); struct callback *add_memory_usage_callback(callback_func call, void *arg, callback_func free_func); void f__memory_usage(INT32 args); void f__next(INT32 args); void f__prev(INT32 args); void f__refs(INT32 args); void f_replace_master(INT32 args); void f_master(INT32 args); void f_gethrvtime(INT32 args); void f_gethrtime(INT32 args); void f_gethrtime(INT32 args); void f_object_variablep(INT32 args); void f_splice(INT32 args); void f_everynth(INT32 args); void f_transpose(INT32 args); void f__reset_dmalloc(INT32 args); void f__locate_references(INT32 args); void f_map_array(INT32 args);

error.h Error functions.

void error(contant char *fmt, ...)

This function throws an error, aborting the execution of the function it is in.

fmt A formating string, ala printf. ... Zero or more arguments to be formated on the error string, alal printf.

global.h Defines some Pike contants such as INT16, INT32, INT64, INT_TYPE, etc.

interpret.h Used to get access to the stack related functions. It defines the global stack pointer variable 'sp'.

void pop_stack(void)

Pops one variable from the Pike stack.

void pop_n_elements(int n)

Pops a variable number of variables from the Pike stack.

n How many variables to pop.

void push_program(struct program *prog)

Pushes a Pike program onto the Pike stack.

prog Pike program to push onto the Pike stack.

void push_mapping(struct mapping *map)

Pushes a Pike mapping onto the Pike stack.

map Pike mapping to push onto the Pike stack.

void push_array(struct array *ar)

Pushes a Pike array onto the Pike stack.

ar Pike array to push onto the Pike stack.

void push_multiset(struct multiset *mul)

Pushes a Pike multiset onto the Pike stack.

mul Pike multiset to push onto the Pike stack.

void push_object(struct object *obj)

Pushes a Pike object onto th Pike stack.

obj Pike object to push onto the Pike stack.

void push_int(INT32 i)

Converts a INT32 intger into a Pike integer and pushed it onto the Pike stack.

i The INT32 integer to push onto the Pike stack.

void push_float(float f)

Converts a float into a Pike float and pushes it onto the Pike stack.

f Float to push onto the Pike stack.

void push_text(char *str)

This function creates a Pike string from a C string and pushes it onto the Pike stack.

str C string to push onto the Pike stack.

void push_constant_text(const char *str)

This function creates a constant Pike string from a C string and pushes it onto the Pike stack.

str C string to push onto the Pike stack.

void push_string(struct pike_string *)

This function pushes a Pike string onto the Pike stack.

str Pike string to push onto the Pike stack.

void ref_push_program(struct program *prog)

This function pushes a reference to a Pike program onto the Pike stack.

prog The Pike program which reference to push onto the Pike stack.

void ref_push_mapping(struct mapping *map)

This function pushes a reference to a Pike mapping onto the Pike stack.

map The Pike mapping which reference to push onto the Pike stack.

void ref_push_array(struct array *arr)

This function pushes a reference to a Pike array onto the Pike stack.

arr The Pike array which reference to push onto the Pike stack.

void ref_push_multiset(struct multiset *mul)

This function pushes a reference to a Pike multiset onto the Pike stack.

mul The Pike multiset which reference to push onto the Pike stack.

void ref_push_string(struct string *str)

This function pushes a reference to a Pike string onto the Pike stack.

str The Pike string which reference to push onto the Pike stack.

void ref_push_object(struct object *obj)

This function pushes a reference to a Pike object onto the Pike stack.

obj The Pike object which reference to push onto the Pike stack.

void push_svalue(struct svalue *sv)

This function pushes an svalue onto the Pike stack.

sv svalue to push onto the Pike stack.

void stack_dump(void)

This function pushes onto the Pike stack a reference to the top value in the Pike stack.

void stack_swap(void)

This function swaps the two top variables in the Pike stack.

mapping.h Mapping data type functions.

struct mapping *allocate_mapping(int size); void really_free_mapping(struct mapping *m); void mapping_insert(struct mapping *m,struct svalue *key, struct svalue *val); union anything *mapping_get_item_ptr(struct mapping *m, struct svalue *key, TYPE_T t); void map_delete(struct mapping *m, struct svalue *key); struct svalue *low_mapping_lookup(struct mapping *m, struct svalue *key); struct svalue *low_mapping_string_lookup(struct mapping *m, struct pike_string *p); void mapping_string_insert(struct mapping *m,struct pike_string *p, struct svalue *val); struct svalue *simple_mapping_string_lookup(struct mapping *m, char *p); void mapping_index_no_free(struct svalue *dest, struct mapping *m, struct svalue *key); struct array *mapping_indices(struct mapping *m); struct array *mapping_values(struct mapping *m); struct array *mapping_to_array(struct mapping *m); void mapping_replace(struct mapping *m,struct svalue *from, struct svalue *to); struct mapping *mkmapping(struct array *ind, struct array *val); struct mapping *copy_mapping(struct mapping *m); struct mapping *merge_mappings(struct mapping *a, struct mapping *b, INT32 op); struct mapping *add_mappings(struct svalue *argp, INT32 args); int mapping_equal_p(struct mapping *a, struct mapping *b, struct processing *p);void describe_mapping(struct mapping *m,struct processing *p,int indent); struct mapping *copy_mapping_recursively(struct mapping *m, struct processing *p); void mapping_search_no_free(struct svalue *to, struct mapping *m, struct svalue *look_for, struct svalue *start);

module_support.h Functions to get arguments from the stack without actually looking at it.

int check_args(int args, ...); void check_all_args(const char *fnname, int args, … ); int va_get_args(struct svalue *s, INT32 num_args, char *fmt, va_list ap); int get_args(struct svalue *s, INT32 num_args, char *fmt, ...); void get_all_args(char *fname, INT32 args, char *format, … );

multiset.h Multiset data type functions.

void free_multiset(struct multiset *mul)

Deallocate a Pike multiset.

mul Pike multiset to deallocate.

INT32 l_sizeof(struct multiset *mul)

Returns the number of elements in the multiset.

int multiset_member(struct multiset *l, struct svalue *ind); struct multiset *mkmultiset(struct array *ind); void multiset_insert(struct multiset *l, struct svalue *ind); struct array *multiset_indices(struct multiset *l); void multiset_delete(struct multiset *l,struct svalue *ind); void check_multiset_for_destruct(struct multiset *l); struct multiset *copy_multiset(struct multiset *tmp); struct multiset *merge_multisets(struct multiset *a, struct multiset *b, INT32 operator); struct multiset *add_multisets(struct svalue *argp,INT32 args); int multiset_equal_p(struct multiset *a, struct multiset *b, struct processing *p); struct multiset *copy_multiset_recursively(struct multiset *l, struct processing *p);

object.h Object data type functions.

void free_object(struct object *obj)

Deallocate a Pike object.

obj Pike object to deallocate.

struct object *low_clone(struct program *p); void call_c_initializers(struct object *o); void do_free_object(struct object *o); struct object *parent_clone_object(struct program *p, struct object *parent, int parent_identifier, int args); struct object *get_master(void); struct object *master(void); void destruct(struct object *o); union anything *object_get_item_ptr(struct object *o, struct svalue *index, TYPE_T type); int object_equal_p(struct object *a, struct object *b, struct processing *p); struct array *object_indices(struct object *o); struct array *object_values(struct object *o); struct object *clone_object(struct program *p, int args)

program.h Program creation related functions, such as add_function.

void start_new_program(void)

Start building a new program.

struct program *end_program(void)

Finish building a new program. Returns a pointer to the finished Pike program. You must deallocate the returned program structure when the module exists using free_program().

int end_program(char *name, INT32 flags)

Finishes building a new program and adds it to the parent program with an identifier of "name".

name Name of the new program. flags Flags.

void free_program(struct program *prog)

Deallocate a program structure.

int add_function(char *name, void (*callback)(INT32), char *type, int flags)

This function adds a function to the current class (program).

name Name of the function. callback Callback that implements the function. type The type of the function. flags Flags field. Possible values are: ID_STATIC, ID_PRIVATE, ID_NOMASK, ID_PUBLIC, ID_PROTECTED, ID_INLINE, ID_HIDDEN, and ID_INHERITED.

Example:

add_function("create", f_create, "function(string|void, string|void, string|void, string|void:void)", ID_PUBLIC);

SITE_T add_storage(SIZE_T size)

This function allocated storage needed for this program in the object structure. An offset to the data is returned. You can access the allocated storage via the frame pointer as fp->current_storage.

size How much memory to allocate.

void add_program_constant(char *name, struct program *prog, INT32 flags)

This function adds a (sub)program to the current new program. The (sub)program can be accessed using the "." operator.

name The name of the (sub)program. prog Pike programm to add. flags Flags field.

void set_init_callback(void (*init)(struct object *))

Sets a callback function used to initialize clones of this program. It is called at clone time.

init Callback functin that takes a pointer to a Pike object to initialize and returns void.

void set_exit_callback(void (*exit)(struct object *))

Sets a callback function to de-initialize clones of this program. It is called at destruct time.

exit Callback function that takes a pointer to a Pike object to de-initialize and returns void.

int map_variable(char *name, char *type, INT32 flags, INT32 offset, INT32 run_time_type); int define_variable(struct pike_string *name, struct pike_string *type, INT32 flags); int simple_add_variable(char *name, char *type, INT32 flags); int add_constant(struct pike_string *name, struct svalue *c, INT32 flags); int simple_add_constant(char *name, struct svalue *c, INT32 flags); int add_integer_constant(char *name, INT32 i, INT32 flags); int add_float_constant(char *name, double f, INT32 flags); int add_string_constant(char *name, char *str, INT32 flags); int add_program_constant(char *name, struct program *p, INT32 flags); int add_object_constant(char *name, struct object *o, INT32 flags); int add_function_constant(char *name, void (*cfun)(INT32), char * type, INT16 flags);

stralloc.h String data type functions.

void free_string(struct pike_string *str)

Deallocate a Pike string.

str Pike string to deallocate.

struct pike_string * make_shared_string(const char *str)

This function created a shared Pike string from a C string.

str C string to make into a shared Pike string.

struct pike_string * copy_shared_string(struct pike_string *to, struct pike_string *from)

This function makes a shared copy of a Pike string.

INLINE unsigned INT32 index_shared_string(struct pike_string *s, int pos) INLINE void pike_string_cpy(PCHARP to, struct pike_string *from); int string_search(struct pike_string *haystack, struct pike_string *needle, int start); struct pike_string *string_slice(struct pike_string *s, INT32 start, INT32 len); struct pike_string *string_replace(struct pike_string *str, struct pike_string *del, struct pike_string *to);


Powered by PikeWiki2

 
gotpike.org | Copyright © 2004 - 2009 | Pike is a trademark of Department of Computer and Information Science, Linköping University