In Files

  • dl/cfunc.c

DL::CFunc

Public Class Methods

last_error() click to toggle source
 
               static VALUE
rb_dl_get_last_error(VALUE self)
{
    return rb_thread_local_aref(rb_thread_current(), id_last_error);
}
            
new(p1, p2 = v2, p3 = v3, p4 = v4) click to toggle source
 
               VALUE
rb_dlcfunc_initialize(int argc, VALUE argv[], VALUE self)
{
    VALUE addr, name, type, calltype;
    struct cfunc_data *data;
    void *saddr;
    const char *sname;
    
    rb_scan_args(argc, argv, "13", &addr, &type, &name, &calltype);
    
    saddr = (void*)(NUM2PTR(rb_Integer(addr)));
    sname = NIL_P(name) ? NULL : StringValuePtr(name);
    
    Data_Get_Struct(self, struct cfunc_data, data);
    if( data->name ) xfree(data->name);
    data->ptr  = saddr;
    data->name = sname ? strdup(sname) : 0;
    data->type = (type == Qnil) ? DLTYPE_VOID : NUM2INT(type);
    data->calltype = (calltype == Qnil) ? CFUNC_CDECL : SYM2ID(calltype);

    return Qnil;
}
            
win32_last_error() click to toggle source
 
               static VALUE
rb_dl_get_win32_last_error(VALUE self)
{
    return rb_thread_local_aref(rb_thread_current(), id_win32_last_error);
}
            

Public Instance Methods

[](p1) click to toggle source
 
               VALUE
rb_dlcfunc_call(VALUE self, VALUE ary)
{
    struct cfunc_data *cfunc;
    int i;
    DLSTACK_TYPE stack[DLSTACK_SIZE];
    VALUE result = Qnil;

    rb_secure_update(self);

    memset(stack, 0, sizeof(DLSTACK_TYPE) * DLSTACK_SIZE);
    Check_Type(ary, T_ARRAY);
    
    Data_Get_Struct(self, struct cfunc_data, cfunc);

    if( cfunc->ptr == 0 ){
        rb_raise(rb_eDLError, "can't call null-function");
        return Qnil;
    }
    
    for( i = 0; i < RARRAY_LEN(ary); i++ ){
        if( i >= DLSTACK_SIZE ){
            rb_raise(rb_eDLError, "too many arguments (stack overflow)");
        }
        rb_check_safe_obj(RARRAY_PTR(ary)[i]);
        stack[i] = NUM2LONG(RARRAY_PTR(ary)[i]);
    }
    
    /* calltype == CFUNC_CDECL */
    if( cfunc->calltype == CFUNC_CDECL
#ifndef FUNC_STDCALL
        || cfunc->calltype == CFUNC_STDCALL
#endif
        ){
        switch( cfunc->type ){
        case DLTYPE_VOID:
#define CASE(n) case n: { \
            DECL_FUNC_CDECL(f,void,DLSTACK_PROTO##n) = cfunc->ptr; \
            f(DLSTACK_ARGS##n(stack)); \
            result = Qnil; \
}
            
call(p1) click to toggle source
 
               VALUE
rb_dlcfunc_call(VALUE self, VALUE ary)
{
    struct cfunc_data *cfunc;
    int i;
    DLSTACK_TYPE stack[DLSTACK_SIZE];
    VALUE result = Qnil;

    rb_secure_update(self);

    memset(stack, 0, sizeof(DLSTACK_TYPE) * DLSTACK_SIZE);
    Check_Type(ary, T_ARRAY);
    
    Data_Get_Struct(self, struct cfunc_data, cfunc);

    if( cfunc->ptr == 0 ){
        rb_raise(rb_eDLError, "can't call null-function");
        return Qnil;
    }
    
    for( i = 0; i < RARRAY_LEN(ary); i++ ){
        if( i >= DLSTACK_SIZE ){
            rb_raise(rb_eDLError, "too many arguments (stack overflow)");
        }
        rb_check_safe_obj(RARRAY_PTR(ary)[i]);
        stack[i] = NUM2LONG(RARRAY_PTR(ary)[i]);
    }
    
    /* calltype == CFUNC_CDECL */
    if( cfunc->calltype == CFUNC_CDECL
#ifndef FUNC_STDCALL
        || cfunc->calltype == CFUNC_STDCALL
#endif
        ){
        switch( cfunc->type ){
        case DLTYPE_VOID:
#define CASE(n) case n: { \
            DECL_FUNC_CDECL(f,void,DLSTACK_PROTO##n) = cfunc->ptr; \
            f(DLSTACK_ARGS##n(stack)); \
            result = Qnil; \
}
            
calltype() click to toggle source
 
               VALUE
rb_dlcfunc_calltype(VALUE self)
{
    struct cfunc_data *cfunc;

    Data_Get_Struct(self, struct cfunc_data, cfunc);
    return ID2SYM(cfunc->calltype);
}
            
calltype=(p1) click to toggle source
 
               VALUE
rb_dlcfunc_set_calltype(VALUE self, VALUE sym)
{
    struct cfunc_data *cfunc;

    Data_Get_Struct(self, struct cfunc_data, cfunc);
    cfunc->calltype = SYM2ID(sym);
    return sym;
}
            
ctype() click to toggle source
 
               VALUE
rb_dlcfunc_ctype(VALUE self)
{
    struct cfunc_data *cfunc;

    Data_Get_Struct(self, struct cfunc_data, cfunc);
    return INT2NUM(cfunc->type);
}
            
ctype=(p1) click to toggle source
 
               VALUE
rb_dlcfunc_set_ctype(VALUE self, VALUE ctype)
{
    struct cfunc_data *cfunc;

    Data_Get_Struct(self, struct cfunc_data, cfunc);
    cfunc->type = NUM2INT(ctype);
    return ctype;
}
            
inspect() click to toggle source
 
               VALUE
rb_dlcfunc_inspect(VALUE self)
{
    VALUE val;
    char  *str;
    int str_size;
    struct cfunc_data *cfunc;
    
    Data_Get_Struct(self, struct cfunc_data, cfunc);
    
    str_size = (cfunc->name ? strlen(cfunc->name) : 0) + 100;
    str = ruby_xmalloc(str_size);
    snprintf(str, str_size - 1,
             "#<DL::CFunc:%p ptr=%p type=%d name='%s'>",
             cfunc,
             cfunc->ptr,
             cfunc->type,
             cfunc->name ? cfunc->name : "");
    val = rb_tainted_str_new2(str);
    ruby_xfree(str);

    return val;
}
            
name() click to toggle source
 
               VALUE
rb_dlcfunc_name(VALUE self)
{
    struct cfunc_data *cfunc;

    Data_Get_Struct(self, struct cfunc_data, cfunc);
    return cfunc->name ? rb_tainted_str_new2(cfunc->name) : Qnil;
}
            
ptr() click to toggle source
 
               VALUE
rb_dlcfunc_ptr(VALUE self)
{
    struct cfunc_data *cfunc;

    Data_Get_Struct(self, struct cfunc_data, cfunc);
    return PTR2NUM(cfunc->ptr);
}
            
ptr=(p1) click to toggle source
 
               VALUE
rb_dlcfunc_set_ptr(VALUE self, VALUE addr)
{
    struct cfunc_data *cfunc;

    Data_Get_Struct(self, struct cfunc_data, cfunc);
    cfunc->ptr = NUM2PTR(addr);

    return Qnil;
}
            
to_i() click to toggle source
 
               VALUE
rb_dlcfunc_to_i(VALUE self)
{
  struct cfunc_data *cfunc;

  Data_Get_Struct(self, struct cfunc_data, cfunc);
  return PTR2NUM(cfunc->ptr);
}
            
to_s() click to toggle source
 
               VALUE
rb_dlcfunc_inspect(VALUE self)
{
    VALUE val;
    char  *str;
    int str_size;
    struct cfunc_data *cfunc;
    
    Data_Get_Struct(self, struct cfunc_data, cfunc);
    
    str_size = (cfunc->name ? strlen(cfunc->name) : 0) + 100;
    str = ruby_xmalloc(str_size);
    snprintf(str, str_size - 1,
             "#<DL::CFunc:%p ptr=%p type=%d name='%s'>",
             cfunc,
             cfunc->ptr,
             cfunc->type,
             cfunc->name ? cfunc->name : "");
    val = rb_tainted_str_new2(str);
    ruby_xfree(str);

    return val;
}
            

Commenting is here to help enhance the documentation. For example, code samples, or clarification of the documentation.

If you have questions about Ruby or the documentation, please post to one of the Ruby mailing lists. You will get better, faster, help that way.

If you wish to post a correction of the docs, please do so, but also file bug report so that it can be corrected for the next release. Thank you.

If you want to help improve the Ruby documentation, please visit Documenting-ruby.org.

blog comments powered by Disqus