示例#1
0
文件: Struct.c 项目: mjaric/ffi
static void
struct_malloc(Struct* s)
{
    if (s->rbPointer == Qnil) {
        s->rbPointer = rbffi_MemoryPointer_NewInstance(s->layout->size, 1, true);

    } else if (!rb_obj_is_kind_of(s->rbPointer, rbffi_AbstractMemoryClass)) {
        rb_raise(rb_eRuntimeError, "invalid pointer in struct");
    }

    s->pointer = (AbstractMemory *) DATA_PTR(s->rbPointer);
}
示例#2
0
文件: Struct.c 项目: mjaric/ffi
/*
 * call-seq: initialize_copy(other)
 * @return [nil]
 * DO NOT CALL THIS METHOD
 */
static VALUE
struct_initialize_copy(VALUE self, VALUE other)
{
    Struct* src;
    Struct* dst;
    
    Data_Get_Struct(self, Struct, dst);
    Data_Get_Struct(other, Struct, src);
    if (dst == src) {
        return self;
    }
    
    dst->rbLayout = src->rbLayout;
    dst->layout = src->layout;
    
    /*
     * A new MemoryPointer instance is allocated here instead of just calling
     * #dup on rbPointer, since the Pointer may not know its length, or may
     * be longer than just this struct.
     */
    if (src->pointer->address != NULL) {
        dst->rbPointer = rbffi_MemoryPointer_NewInstance(1, src->layout->size, false);
        dst->pointer = MEMORY(dst->rbPointer);
        memcpy(dst->pointer->address, src->pointer->address, src->layout->size);
    } else {
        dst->rbPointer = src->rbPointer;
        dst->pointer = src->pointer;
    }

    if (src->layout->referenceFieldCount > 0) {
        dst->rbReferences = ALLOC_N(VALUE, dst->layout->referenceFieldCount);
        memcpy(dst->rbReferences, src->rbReferences, dst->layout->referenceFieldCount * sizeof(VALUE));
    }
        
    return self;
}
示例#3
0
文件: Types.c 项目: SFEley/ffi
VALUE
rbffi_NativeValue_ToRuby(Type* type, VALUE rbType, const void* ptr)
{
    switch (type->nativeType) {
        case NATIVE_VOID:
            return Qnil;
        case NATIVE_INT8:
          return INT2NUM((signed char) *(ffi_sarg *) ptr);
        case NATIVE_INT16:
          return INT2NUM((signed short) *(ffi_sarg *) ptr);
        case NATIVE_INT32:
          return INT2NUM((signed int) *(ffi_sarg *) ptr);
        case NATIVE_LONG:
            return LONG2NUM((signed long) *(ffi_sarg *) ptr);
        case NATIVE_INT64:
            return LL2NUM(*(signed long long *) ptr);

        case NATIVE_UINT8:
          return UINT2NUM((unsigned char) *(ffi_arg *) ptr);
        case NATIVE_UINT16:
          return UINT2NUM((unsigned short) *(ffi_arg *) ptr);
        case NATIVE_UINT32:
          return UINT2NUM((unsigned int) *(ffi_arg *) ptr);
        case NATIVE_ULONG:
            return ULONG2NUM((unsigned long) *(ffi_arg *) ptr);
        case NATIVE_UINT64:
            return ULL2NUM(*(unsigned long long *) ptr);

        case NATIVE_FLOAT32:
            return rb_float_new(*(float *) ptr);
        case NATIVE_FLOAT64:
            return rb_float_new(*(double *) ptr);

        case NATIVE_LONGDOUBLE:
	  return rbffi_longdouble_new(*(long double *) ptr);

        case NATIVE_STRING:
            return (*(void **) ptr != NULL) ? rb_tainted_str_new2(*(char **) ptr) : Qnil;
        case NATIVE_POINTER:
            return rbffi_Pointer_NewInstance(*(void **) ptr);
        case NATIVE_BOOL:
            return ((unsigned char) *(ffi_arg *) ptr) ? Qtrue : Qfalse;
        
        case NATIVE_FUNCTION:
        case NATIVE_CALLBACK: {
            return *(void **) ptr != NULL 
                    ? rbffi_Function_NewInstance(rbType, rbffi_Pointer_NewInstance(*(void **) ptr))
                    : Qnil;
        }

        case NATIVE_STRUCT: {
            StructByValue* sbv = (StructByValue *)type;
            AbstractMemory* mem;
            VALUE rbMemory = rbffi_MemoryPointer_NewInstance(1, sbv->base.ffiType->size, false);

            Data_Get_Struct(rbMemory, AbstractMemory, mem);
            memcpy(mem->address, ptr, sbv->base.ffiType->size);
            RB_GC_GUARD(rbMemory);
            RB_GC_GUARD(rbType);

            return rb_class_new_instance(1, &rbMemory, sbv->rbStructClass);
        }

        case NATIVE_MAPPED: {
            /*
             * For mapped types, first convert to the real native type, then upcall to
             * ruby to convert to the expected return type
             */
            MappedType* m = (MappedType *) type;
            VALUE values[2], rbReturnValue;

            values[0] = rbffi_NativeValue_ToRuby(m->type, m->rbType, ptr);
            values[1] = Qnil;
            

            rbReturnValue = rb_funcall2(m->rbConverter, id_from_native, 2, values);
            RB_GC_GUARD(values[0]);
            RB_GC_GUARD(rbType);
            
            return rbReturnValue;
        }
    
        default:
            rb_raise(rb_eRuntimeError, "Unknown type: %d", type->nativeType);
            return Qnil;
    }
}