这里主要目的:用dbus 消息来传递一个大概10K的图片文件。
使用Garray是比较合适的,它可以包含任何类型的数据。实际调试过程中发现:实际的消息大小是图片文件大小的4倍!这是怎么回事?难道是dbus把Garray映射成DBUS_TYPE_ARRAY,而DBUS_TYPE_ARRAY是uint32的数组。其实问题的原因就在这里:你不要在XML文件中定义uint32数组(au),而定义byte 数组(ay), 这样,你的消息体的数据与实际的图片文件大小相符。
代码如下:
//
客户端程序
int main (int argc, char **argv)
{
DBusGConnection *connection;
GError *error;
DBusGProxy *proxy;
GArray *array;
guint length;
FILE *fp = NULL;
int len;
g_type_init ();
error = NULL;
connection = dbus_g_bus_get (DBUS_BUS_SESSION,
&error);
if (connection == NULL)
{
g_printerr ("Failed to open connection to bus: %s/n",
error->message);
g_error_free (error);
exit (1);
}
proxy = dbus_g_proxy_new_for_name (connection,
"com.example.SomeObject",
"/com/example/SomeObject",
"com.example.SomeObject");
error = NULL;
//从消息中读取数据文件,并且把读取的数据写到copy-client文件中 if(!com_example_SomeObject_method1(proxy,10,&array,&length,&error))
{
printf("Error --- %s/n",error->message);
return 1;
}
printf("File details... length = %d/n",length);
error = NULL;
fp = fopen("copy-client","wb");
len = fwrite(array->data,4,array->len,fp);
fclose(fp);
return 0;
}
//server侧的代码:
//some-object.h
#ifndef __SOME_OBJECT_H__
#define __SOME_OBJECT_H__
#include <glib-object.h>
typedef struct _SomeObject SomeObject;
struct _SomeObject
{
GObject parent_obj;
gint m_a;
gchar* m_b;
gfloat m_c;
};
typedef struct _SomeObjectClass SomeObjectClass;
struct _SomeObjectClass
{
GObjectClass parent_class;
/* Some useful methods may follow. */
gboolean (*method1) (SomeObject *self, gint x,GArray **y,gint
*z,GError **error);
void (*method2) (SomeObject *self, gchar*);
};
GType some_object_get_type ();
gboolean some_object_method1 (SomeObject *self, gint x,GArray **y,gint
*z,GError **); /* virtual */
void some_object_method2 (SomeObject *self, gchar*); /* virtual
*/
void some_object_method3 (SomeObject *self, gfloat); /*
non-virtual */
/* Handy macros */
#define SOME_OBJECT_TYPE (some_object_get_type ())
#define SOME_OBJECT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj),
SOME_OBJECT_TYPE, SomeObject))
#define SOME_OBJECT_CLASS(c) (G_TYPE_CHECK_CLASS_CAST ((c),
SOME_OBJECT_TYPE, SomeObjectClass))
#define SOME_IS_OBJECT(obj) (G_TYPE_CHECK_TYPE ((obj),
SOME_OBJECT_TYPE))
#define SOME_IS_OBJECT_CLASS(c) (G_TYPE_CHECK_CLASS_TYPE ((c),
SOME_OBJECT_TYPE))
#define SOME_OBJECT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS
((obj), SOME_OBJECT_TYPE, SomeObjectClass))
#endif
// End some-object.h
/// some-object.c
#include <string.h>
#include <sys/stat.h>
#include <stdio.h>
#include <stdlib.h>
#include "some-object.h"
#include "some-object-glue.h"
#include <dbus/dbus-glib-bindings.h>
#include <errno.h>
static GObjectClass *parent_class = ((void *)0);
static void some_object_init (SomeObject *self);
char *FILENAME = "test.jpeg";
int SIZE = 0;
//把图片文件test.jpeg打包到消息体中
gboolean some_object_method1_impl (SomeObject *self, gint a, GArray
**y,gint *z,GError **error)
{
struct stat stat_buf;
gchar *ptr = NULL;
FILE *fp = NULL;
int err;
unsigned int length = 0;
self->m_a = a;
g_print ("Method1: %i/n", self->m_a);
*y = g_array_new(FALSE,FALSE,1);
stat(FILENAME,&stat_buf);
SIZE = stat_buf.st_size;
ptr = g_malloc(SIZE);
errno = 0;
fp = fopen(FILENAME,"rb");
err = errno;
if(fp)
{
FILE *fp2 = fopen("c://copy-server","wb");
fread(ptr,1,SIZE,fp);
if(fp2)
fwrite(ptr,1,SIZE,fp2);
g_array_append_vals(*y,ptr,SIZE/4);
*z = SIZE;
}
fclose(fp);
free(ptr);
return TRUE;
}
void some_object_method2_impl (SomeObject *self, gchar* b)
{
self->m_b = b;
g_print ("Method2: %s/n", self->m_b);
}
/* Public methods. */
gboolean some_object_method1 (SomeObject *self, gint a,GArray **y,gint
*z,GError **error)
{
return SOME_OBJECT_GET_CLASS (self)->method1 (self, a,y,z,error);
}
void some_object_method2 (SomeObject *self, gchar* b)
{
SOME_OBJECT_GET_CLASS (self)->method2 (self, b);
}
void some_object_method3 (SomeObject *self, gfloat c)
{
self->m_c = c;
g_print ("Method3: %f/n", self->m_c);
}
void some_object_dispose (GObject *self)
{
static gboolean first_run = TRUE;
if (first_run)
{
first_run = FALSE;
/* Call g_object_unref on any GObjects that we hold, but don't
break the object */
parent_class-> dispose (self);
}
}
void some_object_finalize (GObject *self)
{
parent_class-> finalize (self);
}
/* Here is where we override any functions. Since we have no properties
or even fields, none of the below are needed. */
void some_object_class_init (gpointer g_class, gpointer
class_data)
{
GObjectClass *object_class = G_OBJECT_CLASS (g_class);
SomeObjectClass *this_class = SOME_OBJECT_CLASS (g_class);
//assign value to parent class
parent_class = g_type_class_peek_parent (g_class);
//assing pointer values to the base class members
object_class-> dispose = &some_object_dispose;
object_class-> finalize = &some_object_finalize;
//assign value to derived class members
this_class->method1 = &some_object_method1_impl;
this_class->method2 = &some_object_method2_impl;
dbus_g_object_type_install_info(G_TYPE_FROM_CLASS(this_class),&dbus_glib__object_info);
}
void some_object_init (SomeObject *self)
{
self->m_a = 1;
self->m_c = 1.03f;
self->m_b = "sumit";
}
GType some_object_get_type ()
{
static GType g_define_type_id = 0;
if ((g_define_type_id == 0))
{
static const GTypeInfo g_define_type_info =
{
sizeof (SomeObjectClass),
(GBaseInitFunc) ((void *)0),
(GBaseFinalizeFunc) ((void *)0),
(GClassInitFunc) some_object_class_init,
(GClassFinalizeFunc) ((void *)0),
((void *)0),
sizeof (SomeObject),
0,
(GInstanceInitFunc) some_object_init,
};
g_define_type_id = g_type_register_static
(
G_TYPE_OBJECT,
"SomeObject",
&g_define_type_info,
(GTypeFlags) 0
);
}
return g_define_type_id;
}
int main(int argc,char *argv[])
{
SomeObject *so = NULL;
DBusGConnection *bus;
GMainLoop *mainLoop = NULL;
unsigned int request_ret;
GError *error = NULL;
DBusGProxy *proxy = NULL;
char *x;
g_type_init();
so = g_object_new(SOME_OBJECT_TYPE,NULL);
bus = dbus_g_bus_get(DBUS_BUS_SESSION,NULL);
proxy =
dbus_g_proxy_new_for_name(bus,DBUS_SERVICE_DBUS,DBUS_PATH_DBUS,DBUS_INTERFACE_DBUS);
dbus_g_connection_register_g_object(bus,"/com/example/SomeObject",G_OBJECT(so));
if(!org_freedesktop_DBus_request_name(proxy,"com.example.SomeObject",0,&request_ret,&error))
{
g_print("Unable to register service/n");
return 1;
}
mainLoop = g_main_loop_new(NULL,FALSE);
g_main_loop_run(mainLoop);
return 0;
}