Class: FFI::FunctionType
- Inherits:
-
Type
- Object
- Type
- FFI::FunctionType
- Defined in:
- ext/ffi_c/FunctionInfo.c
Instance Method Summary collapse
-
#initialize(return_type, param_types, options = {}) ⇒ self
constructor
A new FunctionType instance.
-
#param_types ⇒ Array<Type>
Get parameters types.
-
#return_type ⇒ Type
Get the return type of the function type.
Constructor Details
#initialize(return_type, param_types, options = {}) ⇒ self
A new FunctionType instance.
164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 |
# File 'ext/ffi_c/FunctionInfo.c', line 164
static VALUE
fntype_initialize(int argc, VALUE* argv, VALUE self)
{
FunctionType *fnInfo;
ffi_status status;
VALUE rbReturnType = Qnil, rbParamTypes = Qnil, rbOptions = Qnil;
VALUE rbEnums = Qnil, rbConvention = Qnil, rbBlocking = Qnil;
#if defined(X86_WIN32)
VALUE rbConventionStr;
#endif
int i, nargs;
nargs = rb_scan_args(argc, argv, "21", &rbReturnType, &rbParamTypes, &rbOptions);
if (nargs >= 3 && rbOptions != Qnil) {
rbConvention = rb_hash_aref(rbOptions, ID2SYM(rb_intern("convention")));
rbEnums = rb_hash_aref(rbOptions, ID2SYM(rb_intern("enums")));
rbBlocking = rb_hash_aref(rbOptions, ID2SYM(rb_intern("blocking")));
}
Check_Type(rbParamTypes, T_ARRAY);
TypedData_Get_Struct(self, FunctionType, &rbffi_fntype_data_type, fnInfo);
fnInfo->parameterCount = RARRAY_LENINT(rbParamTypes);
fnInfo->parameterTypes = xcalloc(fnInfo->parameterCount, sizeof(*fnInfo->parameterTypes));
fnInfo->ffiParameterTypes = xcalloc(fnInfo->parameterCount, sizeof(ffi_type *));
fnInfo->nativeParameterTypes = xcalloc(fnInfo->parameterCount, sizeof(*fnInfo->nativeParameterTypes));
RB_OBJ_WRITE(self, &fnInfo->rbParameterTypes, rb_ary_new2(fnInfo->parameterCount));
RB_OBJ_WRITE(self, &fnInfo->rbEnums, rbEnums);
fnInfo->blocking = RTEST(rbBlocking);
fnInfo->hasStruct = false;
for (i = 0; i < fnInfo->parameterCount; ++i) {
VALUE entry = rb_ary_entry(rbParamTypes, i);
VALUE type = rbffi_Type_Lookup(entry);
if (!RTEST(type)) {
VALUE typeName = rb_funcall2(entry, rb_intern("inspect"), 0, NULL);
rb_raise(rb_eTypeError, "Invalid parameter type (%s)", RSTRING_PTR(typeName));
}
if (rb_obj_is_kind_of(type, rbffi_FunctionTypeClass)) {
REALLOC_N(fnInfo->callbackParameters, VALUE, fnInfo->callbackCount + 1);
RB_OBJ_WRITE(self, &fnInfo->callbackParameters[fnInfo->callbackCount], type);
fnInfo->callbackCount++;
}
if (rb_obj_is_kind_of(type, rbffi_StructByValueClass)) {
fnInfo->hasStruct = true;
}
rb_ary_push(fnInfo->rbParameterTypes, type);
TypedData_Get_Struct(type, Type, &rbffi_type_data_type, fnInfo->parameterTypes[i]);
fnInfo->ffiParameterTypes[i] = fnInfo->parameterTypes[i]->ffiType;
fnInfo->nativeParameterTypes[i] = fnInfo->parameterTypes[i]->nativeType;
}
RB_OBJ_WRITE(self, &fnInfo->rbReturnType, rbffi_Type_Lookup(rbReturnType));
if (!RTEST(fnInfo->rbReturnType)) {
VALUE typeName = rb_funcall2(rbReturnType, rb_intern("inspect"), 0, NULL);
rb_raise(rb_eTypeError, "Invalid return type (%s)", RSTRING_PTR(typeName));
}
if (rb_obj_is_kind_of(fnInfo->rbReturnType, rbffi_StructByValueClass)) {
fnInfo->hasStruct = true;
}
TypedData_Get_Struct(fnInfo->rbReturnType, Type, &rbffi_type_data_type, fnInfo->returnType);
fnInfo->ffiReturnType = fnInfo->returnType->ffiType;
#if defined(X86_WIN32)
rbConventionStr = (rbConvention != Qnil) ? rb_funcall2(rbConvention, rb_intern("to_s"), 0, NULL) : Qnil;
fnInfo->abi = (rbConventionStr != Qnil && strcmp(StringValueCStr(rbConventionStr), "stdcall") == 0)
? FFI_STDCALL : FFI_DEFAULT_ABI;
#else
fnInfo->abi = FFI_DEFAULT_ABI;
#endif
status = ffi_prep_cif(&fnInfo->ffi_cif, fnInfo->abi, fnInfo->parameterCount,
fnInfo->ffiReturnType, fnInfo->ffiParameterTypes);
switch (status) {
case FFI_BAD_ABI:
rb_raise(rb_eArgError, "Invalid ABI specified");
case FFI_BAD_TYPEDEF:
rb_raise(rb_eArgError, "Invalid argument type specified");
case FFI_OK:
break;
default:
rb_raise(rb_eArgError, "Unknown FFI error");
}
fnInfo->invoke = rbffi_GetInvoker(fnInfo);
rb_obj_freeze(fnInfo->rbParameterTypes);
rb_obj_freeze(self);
return self;
}
|
Instance Method Details
#param_types ⇒ Array<Type>
Get parameters types.
281 282 283 284 285 286 287 288 289 |
# File 'ext/ffi_c/FunctionInfo.c', line 281
static VALUE
fntype_param_types(VALUE self)
{
FunctionType* ft;
TypedData_Get_Struct(self, FunctionType, &rbffi_fntype_data_type, ft);
return rb_ary_dup(ft->rbParameterTypes);
}
|
#return_type ⇒ Type
Get the return type of the function type
266 267 268 269 270 271 272 273 274 |
# File 'ext/ffi_c/FunctionInfo.c', line 266
static VALUE
fntype_return_type(VALUE self)
{
FunctionType* ft;
TypedData_Get_Struct(self, FunctionType, &rbffi_fntype_data_type, ft);
return ft->rbReturnType;
}
|