Пример #1
0
static VALUE
rg_symbol(VALUE self)
{
    GIFunctionInfo *info;

    info = SELF(self);
    return CSTR2RVAL(g_function_info_get_symbol(info));
}
Пример #2
0
/**
 * g_function_info_invoke: (skip)
 * @info: a #GIFunctionInfo describing the function to invoke
 * @in_args: an array of #GIArgument<!-- -->s, one for each in
 *    parameter of @info. If there are no in parameter, @in_args
 *    can be %NULL
 * @n_in_args: the length of the @in_args array
 * @out_args: an array of #GIArgument<!-- -->s, one for each out
 *    parameter of @info. If there are no out parameters, @out_args
 *    may be %NULL
 * @n_out_args: the length of the @out_args array
 * @return_value: return location for the return value of the
 *    function. If the function returns void, @return_value may be
 *    %NULL
 * @error: return location for detailed error information, or %NULL
 *
 * Invokes the function described in @info with the given
 * arguments. Note that inout parameters must appear in both
 * argument lists. This function uses dlsym() to obtain a pointer
 * to the function, so the library or shared object containing the
 * described function must either be linked to the caller, or must
 * have been g_module_symbol()<!-- -->ed before calling this function.
 *
 * Returns: %TRUE if the function has been invoked, %FALSE if an
 *   error occurred.
 */
gboolean
g_function_info_invoke (GIFunctionInfo *info,
			const GIArgument  *in_args,
			int               n_in_args,
			const GIArgument  *out_args,
			int               n_out_args,
			GIArgument        *return_value,
			GError          **error)
{
  const gchar *symbol;
  gpointer func;
  gboolean is_method;
  gboolean throws;

  symbol = g_function_info_get_symbol (info);

  if (!g_typelib_symbol (g_base_info_get_typelib((GIBaseInfo *) info),
                         symbol, &func))
    {
      g_set_error (error,
                   G_INVOKE_ERROR,
                   G_INVOKE_ERROR_SYMBOL_NOT_FOUND,
                   "Could not locate %s: %s", symbol, g_module_error ());

      return FALSE;
    }

  is_method = (g_function_info_get_flags (info) & GI_FUNCTION_IS_METHOD) != 0
    && (g_function_info_get_flags (info) & GI_FUNCTION_IS_CONSTRUCTOR) == 0;
  throws = g_function_info_get_flags (info) & GI_FUNCTION_THROWS;

  return g_callable_info_invoke ((GICallableInfo*) info,
                                 func,
                                 in_args,
                                 n_in_args,
                                 out_args,
                                 n_out_args,
                                 return_value,
                                 is_method,
                                 throws,
                                 error);
}
Пример #3
0
gboolean
plgi_main_loop_service_task(gpointer data)
{
  PLGITask *task = data;
  gboolean ret;

  PLGI_debug("  servicing function: %s()",
             g_function_info_get_symbol(task->callable_info->info));

  ret = g_function_info_invoke(task->callable_info->info,
                               task->in_args, task->callable_info->n_in_args,
                               task->out_args, task->callable_info->n_out_args,
                               task->return_arg, &task->error);

  task->ret = ret;
  PLGI_debug("    function retval: %d", ret);
  task->completed = TRUE;

  return G_SOURCE_REMOVE;
}
/**
 * g_function_info_prep_invoker:
 * @info: A #GIFunctionInfo
 * @invoker: Output invoker structure
 * @error: A #GError
 *
 * Initialize the caller-allocated @invoker structure with a cache
 * of information needed to invoke the C function corresponding to
 * @info with the platform's default ABI.
 *
 * A primary intent of this function is that a dynamic structure allocated
 * by a language binding could contain a #GIFunctionInvoker structure
 * inside the binding's function mapping.
 *
 * Returns: %TRUE on success, %FALSE otherwise with @error set.
 */
gboolean
g_function_info_prep_invoker (GIFunctionInfo       *info,
                              GIFunctionInvoker    *invoker,
                              GError              **error)
{
  const char *symbol;
  ffi_type *rtype;
  ffi_type **atypes;
  GITypeInfo *tinfo;
  GIArgInfo *ainfo;
  gboolean is_method;
  gboolean throws;
  gint n_args, n_invoke_args, i;

  g_return_val_if_fail (info != NULL, FALSE);
  g_return_val_if_fail (invoker != NULL, FALSE);

  symbol = g_function_info_get_symbol ((GIFunctionInfo*) info);

  if (!g_typelib_symbol (g_base_info_get_typelib((GIBaseInfo *) info),
                         symbol, &(invoker->native_address)))
    {
      g_set_error (error,
                   G_INVOKE_ERROR,
                   G_INVOKE_ERROR_SYMBOL_NOT_FOUND,
                   "Could not locate %s: %s", symbol, g_module_error ());

      return FALSE;
    }

  is_method = (g_function_info_get_flags (info) & GI_FUNCTION_IS_METHOD) != 0
    && (g_function_info_get_flags (info) & GI_FUNCTION_IS_CONSTRUCTOR) == 0;
  throws = g_function_info_get_flags (info) & GI_FUNCTION_THROWS;

  tinfo = g_callable_info_get_return_type ((GICallableInfo *)info);
  rtype = g_type_info_get_ffi_type (tinfo);
  g_base_info_unref ((GIBaseInfo *)tinfo);

  n_args = g_callable_info_get_n_args ((GICallableInfo *)info);
  if (is_method)
    n_invoke_args = n_args+1;
  else
    n_invoke_args = n_args;

  if (throws)
    /* Add an argument for the GError */
    n_invoke_args ++;

  /* TODO: avoid malloc here? */
  atypes = g_malloc0 (sizeof (ffi_type*) * n_invoke_args);

  if (is_method)
    {
      atypes[0] = &ffi_type_pointer;
    }
  for (i = 0; i < n_args; i++)
    {
      int offset = (is_method ? 1 : 0);
      ainfo = g_callable_info_get_arg ((GICallableInfo *)info, i);
      switch (g_arg_info_get_direction (ainfo))
        {
          case GI_DIRECTION_IN:
            tinfo = g_arg_info_get_type (ainfo);
            atypes[i+offset] = g_type_info_get_ffi_type (tinfo);
            g_base_info_unref ((GIBaseInfo *)tinfo);
            break;
          case GI_DIRECTION_OUT:
          case GI_DIRECTION_INOUT:
            atypes[i+offset] = &ffi_type_pointer;
    	    break;
          default:
            g_assert_not_reached ();
        }
      g_base_info_unref ((GIBaseInfo *)ainfo);
    }

  if (throws)
    {
      atypes[n_invoke_args - 1] = &ffi_type_pointer;
    }

  return ffi_prep_cif (&(invoker->cif), FFI_DEFAULT_ABI, n_invoke_args, rtype, atypes) == FFI_OK;
}