DBus send byte array over gdbus ----Send dbus data

遇到一个问题,如何通过dbus传送uint8数组元素

有3种方法,

1.直接传 ay

2.传  a(y)

3.xml定义为 ay,但是通过annotation 强行将 guchar 转为GVariant 

可以参考:

http://stackoverflow.com/questions/22937588/how-to-send-byte-array-over-gdbus

https://developer.gnome.org/gio/stable/gdbus-codegen.html

如下图3中方法的xml示意

    <signal name="test_method">
      <arg name="addr"  direction="in"  type="ay"/>
      <doc>
        <line>this means send the address of the array</line>
      </doc>
      <arg name="length" direction="in" type="i"/>
    </signal>

    <signal name="test_method_2">
      <arg name="addr"  direction="in"  type="a(y)"/>
      <arg name="length" direction="in" type="i"/>
    </signal>

    <signal name="test_method_3">
      <arg name="addr"  direction="in"  type="ay">
      <annotation name="org.gtk.GDBus.C.ForceGVariant" value="true"/>
      </arg>
      <arg name="length" direction="in" type="i"/>
    </signal>

方法一直接上 ay 如果遇到空字符会出错,简单的数组可以这么传,如果连你也不知道数组里面会有什么内容,千万不要用这个,有可能传到一半数据,就结束出错了。

方法二,挺好用,适合大量数据你也不知道里面是什么内容

方法三,对方法一的一种弥补,写了一段测试代码,client端解析有问题,但是没发现问题在哪,同样的一段代码放在server端就可以解析,放在client端就解析出错

上代码

server端:

/////////////////////////////////////////////////////////////////////////////////////////
// Header files
/////////////////////////////////////////////////////////////////////////////////////////
// Own header
#include "common.h"   // Demo bus defines
#include "server.h" 

// System header
#include <gio/gio.h>   // GIO for dbus
#include <glib-2.0/glib.h>   // GLIB for main loop
#include <stdio.h>
#include <pthread.h>
#include <string.h>
#include <sys/types.h>
#include <unistd.h>
#include <pthread.h>

// Generated headers
#include "example.h"

/////////////////////////////////////////////////////////////////////////////////////////
// Instance init
/////////////////////////////////////////////////////////////////////////////////////////
static GMainLoop         *pLoop     = NULL;
static ContiExampleInterface *pSkeleton = NULL;
static int callNum = 0;

/////////////////////////////////////////////////////////////////////////////////////////
// Normal functions
/////////////////////////////////////////////////////////////////////////////////////////
static gboolean Emit_My_signal1(gconstpointer p)
{
    gchar buf[20];
    
    memset(buf, 0, 20);
    callNum++;
    sprintf(buf, "Server Signal1(%d)", callNum);
    conti_example_interface_emit_my_signal1(pSkeleton, buf);
    return TRUE;
}

static gboolean Emit_My_Signal2(gconstpointer p)
{
  callNum++;
  GVariant *payload = g_variant_new("(is)", callNum, "Server Signal2");
  conti_example_interface_emit_my_signal2(pSkeleton, payload);
  //g_print("Emit_My_Signal2() is called.
");
  return TRUE;
}
void test_Signal()
{  
  unsigned char arrtest[10]={1,2,3,4,5,6,7,8,9};

  conti_example_interface_emit_test_method (pSkeleton,arrtest,10);
  printf("test_Signal end
");
}


static gboolean Emit_My_test_Signal(gconstpointer p)
{
  test_Signal();
  return TRUE;
}

void test_Signal_2()
{  
  unsigned char arrtest[10]={11,12,13,14,15,16,17,18,19};

  GVariantBuilder *builder;
  GVariant *value;

  builder = g_variant_builder_new (G_VARIANT_TYPE ("a(y)"));
  for (int i = 0; i < 10; i++)
  {
    g_variant_builder_add (builder, "(y)", arrtest[i]);
  }
  value = g_variant_new ("a(y)", builder);
  g_variant_builder_unref (builder);

  conti_example_interface_emit_test_method_2 (pSkeleton,value,10);
  printf("test_Signal_2 end
");
}
static gboolean Emit_My_test_Signal_2(gconstpointer p)
{
  test_Signal_2();
  return TRUE;
}


void Test_Extract(GVariant *arg_addr)
{
    unsigned char byteArray[1024];

  int lengi=0;
  GVariantIter *iter;
  guchar data;
  printf("start : 
");

  g_variant_get (arg_addr, "ay", &iter);  
  printf("iter end : 
");

  while (g_variant_iter_loop (iter, "y", &data))
  {
    byteArray[lengi++] = data;
  }
  g_variant_iter_free (iter);  
  printf("test_method_handler_3 data is: %d %d %d %d %d %d %d %d %d
", byteArray,*(byteArray),*(byteArray+1),*(byteArray+2),*(byteArray+3),*(byteArray+4),*(byteArray+5),*(byteArray+6),*(byteArray+7),*(byteArray+8));

}
void test_Signal_3()
{  
  unsigned char arrtest[10]={21,22,113,114,115,116,117,118,119};

  GVariantBuilder *builder;
  GVariant *value;

  builder = g_variant_builder_new (G_VARIANT_TYPE ("ay"));
  for (int i = 0; i < 10; i++)
  {
    g_variant_builder_add (builder, "y", arrtest[i]);
  }
  value = g_variant_new ("ay", builder);
  g_variant_builder_unref (builder);
  Test_Extract(value);
  conti_example_interface_emit_test_method_3 (pSkeleton,value,10);
  printf("test_Signal_3 end
");
}

static gboolean Emit_My_test_Signal_3(gconstpointer p)
{
  test_Signal_3();
  return TRUE;
}
static gboolean My_Method1(ContiExampleInterface     *object,
                               GDBusMethodInvocation *invocation,
                               const gchar           *in_arg,
                               gpointer               user_data)
{
    g_print("Received method call. Parameter: %s.
", in_arg);
    
    //conti_gdbus_example_set_my_property(pSkeleton, "Server Method...");
    //conti_gdbus_example_complete_my_method(object, invocation, "Server Method");
    conti_example_interface_complete_my_method1(object, invocation, in_arg);

    return TRUE;
}

static gboolean My_Method2(ContiExampleInterface     *object,
                               GDBusMethodInvocation *invocation,
                               GVariant           *in_arg,
                               gpointer               user_data)
{
  gint in_arg1 = 0;
  gint in_arg2 = 0;
  gint out_arg2 = 0;
  gchar *out_arg1 = "My Method2";
  GVariant *out_arg = NULL;
  
  // Get the input parameters
  g_variant_get(in_arg, "(ii)", &in_arg1, &in_arg2);
  
  // Generate the output parameters
  out_arg2 = in_arg1 + in_arg2;
  out_arg = g_variant_new("(si)", out_arg1, out_arg2);
 
  conti_example_interface_complete_my_method2(object, invocation, out_arg);

  return TRUE;
}

/////////////////////////////////////////////////////////////////////////////////////////
// Callback functions
/////////////////////////////////////////////////////////////////////////////////////////
static void bus_acquired_cb(GDBusConnection *connection,
                                const gchar     *bus_name,
                                gpointer         user_data)
{
    GError *pError = NULL;

    // Second step: Try to get a connection to the given bus.
    pSkeleton = conti_example_interface_skeleton_new();

    // Third step: Attach to dbus signals
    (void) g_signal_connect(pSkeleton, "handle-my-method1", G_CALLBACK(My_Method1), NULL);
    (void) g_signal_connect(pSkeleton, "handle-my-method2", G_CALLBACK(My_Method2), NULL);

    // Fourth step: Export interface skeleton
    (void) g_dbus_interface_skeleton_export(G_DBUS_INTERFACE_SKELETON(pSkeleton),
                                              connection,
                                              CONTI_GDBUS_EXAMPLE_OBJECT_PATH,
                                              &pError);

    if(pError != NULL)
    {
         g_print("Error: Failed to export object. Reason: %s.
", pError->message);
         g_error_free(pError);
         g_main_loop_quit(pLoop);
    }
}

static void name_acquired_cb(GDBusConnection *connection,
                                     const gchar     *bus_name,
                                     gpointer         user_data)
{
    g_print("Acquired bus name: %s.
", CONTI_GDBUS_EXAMPLE_BUS_NAME);
}


static void name_lost_cb(GDBusConnection *connection,
                             const gchar     *bus_name,
                             gpointer         user_data)
{
    if(connection == NULL)
    {
        g_print("Error: Failed to connect to dbus.
");
    }
    else
    {
        g_print("Error: Failed to obtain bus name: %s.
", CONTI_GDBUS_EXAMPLE_BUS_NAME);
    }

    g_main_loop_quit(pLoop);
}

/////////////////////////////////////////////////////////////////////////////////////////
// Thread functions
/////////////////////////////////////////////////////////////////////////////////////////
int thread_create()
{
    int err;
    pthread_t thr;

    void *thr_fn(void *arg)
    {
        return((void *)0);
    }

    err = pthread_create(&thr, NULL, thr_fn, NULL);

    if (err != 0)
    {
        printf("Can't create thread: %s
", strerror(err));
    }
    else
    {
        printf("New thread created: %s
", strerror(err));
    }

    return err;
}


void create()
{
    // Start Dbus communication
    startDBusCommunication();

    // Create new thread
    //thread_create();
}

void run()
{
    // Start the Main Event Loop which manages all available sources of events
    g_main_loop_run( pLoop );
}

void stop()
{
    // Stop Dbus communication
    stopDBusCommunication();
}

/////////////////////////////////////////////////////////////////////////////////////////
// Dbus communication functions
/////////////////////////////////////////////////////////////////////////////////////////
int startDBusCommunication()
{
    int bRet = TRUE;
    
    // Init for usage of "g" types
    g_type_init();

    g_print("startDBusCommunication: Server started.
");

    // Create main loop, but do not start it.
    pLoop = g_main_loop_new(NULL, FALSE);

    // First step: Connect to dbus        
    (void) g_bus_own_name(CONTI_GDBUS_EXAMPLE_BUS,
                        CONTI_GDBUS_EXAMPLE_BUS_NAME,
                        G_BUS_NAME_OWNER_FLAGS_NONE,
                        &bus_acquired_cb,
                        &name_acquired_cb,
                        &name_lost_cb,
                        NULL,
                        NULL);

    // Emit my signal1 every 1 second to trigger example communication
    //g_timeout_add(1000, &Emit_My_signal1, NULL);
    
    // Emit my signal2 every 2 second to trigger example communication
    //g_timeout_add(2000, &Emit_My_Signal2, NULL);


    g_timeout_add(2000, &Emit_My_test_Signal, NULL);
    g_timeout_add(2000, &Emit_My_test_Signal_2, NULL);
    g_timeout_add(2000, &Emit_My_test_Signal_3, NULL);


    return (bRet);  
}

int stopDBusCommunication()
{
    int bRet = FALSE;

    if (pLoop != 0)
    {
        g_main_loop_quit(pLoop);
        g_main_loop_unref(pLoop);
        bRet = TRUE;
    }

    return (bRet);
}
View Code

client端:

/////////////////////////////////////////////////////////////////////////////////////////
// Header files
/////////////////////////////////////////////////////////////////////////////////////////
// Own header
#include "common.h"   // Demo bus defines
#include "client.h"
#include "client_version.h" 

// System header
#include <gio/gio.h>   // GIO for dbus
#include <glib-2.0/glib.h>   // GLIB for main loop
#include <pthread.h>
#include <stdlib.h>
#include <stdio.h>
#include <pthread.h>
#include <string.h>
#include <sys/types.h>
#include <unistd.h>
#include <string.h>

// Generated headers
#include "example.h"

/////////////////////////////////////////////////////////////////////////////////////////
// Instance init
/////////////////////////////////////////////////////////////////////////////////////////
static GMainLoop         *g_pLoop       = NULL;
static GDBusConnection   *g_pConnection = NULL;
static ContiExampleInterface *g_pProxcy     = NULL;
static pthread_mutex_t g_mutex = PTHREAD_MUTEX_INITIALIZER;

static pthread_mutex_t g_signal_cb_mutex = PTHREAD_MUTEX_INITIALIZER;
static SIGNAL_CALLBACK_T g_signal_callback = {NULL};
static pthread_mutex_t g_method_cb_mutex = PTHREAD_MUTEX_INITIALIZER;
static METHOD_CALLBACK_T g_method_callback = {NULL};

/////////////////////////////////////////////////////////////////////////////////////////
// static function prototype
/////////////////////////////////////////////////////////////////////////////////////////
static void Method1Callback(GObject* source_object, GAsyncResult* res, gpointer user_data);
static void Method2Callback(GObject* source_object, GAsyncResult* res, gpointer user_data);
static gboolean My_Signal_1_Handler(ContiExampleInterface *object, const gchar *arg, gpointer user_data);
static gboolean My_Signal_2_Handler(ContiExampleInterface *object, const GVariant *arg, gpointer user_data);
static gboolean test_method_handler(ContiExampleInterface *object, const gchar  *arg_addr,gint arg_length, gpointer user_data);
static gboolean test_method_handler_2(ContiExampleInterface *object, GVariant *arg_addr,gint arg_length, gpointer user_data);
static gboolean test_method_handler_3(ContiExampleInterface *object, const GVariant *arg_addr,gint arg_length, gpointer user_data);


static void *run(void *arg);
static int thread_create();
static int init_global_var(void);
static void print_version(void);
static int startDBusCommunication();
static int stopDBusCommunication();

/////////////////////////////////////////////////////////////////////////////////////////
// Normal functions
/////////////////////////////////////////////////////////////////////////////////////////
static void Method1Callback(GObject* source_object, GAsyncResult* res, gpointer user_data)
{
  gchar *out_arg = NULL;
  GError *pError = NULL;
  METHOD1CALLBACK callback = NULL;

  conti_example_interface_call_my_method1_finish(g_pProxcy, &out_arg, res, &pError);
  pthread_mutex_lock(&g_signal_cb_mutex);
  callback = g_method_callback.callback1;
  pthread_mutex_unlock(&g_signal_cb_mutex);
  
  if (pError == NULL)
  {
    if(callback != NULL)
    {
      callback(out_arg, false, user_data);
      g_free(out_arg);
    }
  }
  else
  {
    if(callback != NULL)
    {
        callback(out_arg, true, user_data);
        g_print("Method1Callback: error message: %s.
", pError->message);
    }
    g_error_free(pError);
  }
  
}

void My_method_1_Async(const char * in_arg, void *userdata)
{
  conti_example_interface_call_my_method1(g_pProxcy, in_arg, NULL, Method1Callback, userdata);

  return;
}

static void Method2Callback(GObject* source_object, GAsyncResult* res, gpointer user_data)
{
  GVariant *out_arg = NULL;
  GError *pError = NULL;
  gint out_arg2 = 0;
  gchar *out_arg1 = NULL;
  METHOD2CALLBACK callback = NULL;
  
  conti_example_interface_call_my_method2_finish(g_pProxcy, &out_arg, res, &pError);
  pthread_mutex_lock(&g_signal_cb_mutex);
  callback = g_method_callback.callback2;
  pthread_mutex_unlock(&g_signal_cb_mutex);
  if (pError == NULL)
  {
    // Get the result from the output parameter
    g_variant_get(out_arg, "(si)", &out_arg1, &out_arg2);
    if (callback != NULL)
    {
      callback(out_arg1, out_arg2, false, user_data);
      g_free(out_arg1);
    }
  }
  else
  {
    if (callback != NULL)
    {
        callback(out_arg1, out_arg2, true, user_data);
    }
    g_error_free(pError);
  }
}

void My_method_2_Async(const int in_arg1, const int in_arg2, void *userdata)
{
  GVariant *in_arg = g_variant_new("(ii)", in_arg1, in_arg2);

  conti_example_interface_call_my_method2(g_pProxcy, in_arg, NULL, Method2Callback, userdata);
  
  return;
}

void registerSignalCallback(SIGNAL_CALLBACK_T *callback)
{
  if (callback != NULL)
  {
    pthread_mutex_lock(&g_signal_cb_mutex);
    memcpy(&g_signal_callback, callback, sizeof(SIGNAL_CALLBACK_T));
    pthread_mutex_unlock(&g_signal_cb_mutex);
  }
  else
  {
    g_print("registerSignalCallback: parameter point is NULL");
  }
}

void registerMethodCallback(METHOD_CALLBACK_T *callback)
{
  if (callback != NULL)
  {
    pthread_mutex_lock(&g_method_cb_mutex);
    memcpy(&g_method_callback, callback, sizeof(METHOD_CALLBACK_T));
    pthread_mutex_unlock(&g_method_cb_mutex);
  }
  else
  {
    g_print("registerMethodCallback: parameter point is NULL");
  }
}

static gboolean My_Signal_1_Handler(ContiExampleInterface *object,
                                          const gchar       *arg,
                                          gpointer          user_data)
{
    SIGNAL1CALLBACK callback = NULL;

    // callback function
    pthread_mutex_lock(&g_signal_cb_mutex);
    callback = g_signal_callback.callback1;
    pthread_mutex_unlock(&g_signal_cb_mutex);
    if (callback != NULL)
    {
      callback(arg);
    }
    
    return TRUE;
}

static gboolean My_Signal_2_Handler(ContiExampleInterface *object,
                                          const GVariant       *arg,
                                          gpointer          user_data)
{
  // Get the value from GVariant
  gint int_arg = 0;
  gchar *char_arg = NULL;
  SIGNAL2CALLBACK callback = NULL;
  g_variant_get(arg, "(is)", &int_arg, &char_arg);
  
  pthread_mutex_lock(&g_signal_cb_mutex);
  callback = g_signal_callback.callback2;
  pthread_mutex_unlock(&g_signal_cb_mutex);
  // callback function
  if (callback != NULL)
  {
    callback(int_arg, char_arg);
  }
  
  g_free(char_arg);
  return TRUE;
}

static gboolean test_method_handler(ContiExampleInterface *object, const gchar *arg_addr,gint arg_length, gpointer user_data)
{
  unsigned char byteArray[1024];
  GVariantIter *iter;
  guchar str;
  int lengi=0;
  printf("the addr is %d data is: %d %d %d %d %d %d %d %d %d
", arg_addr,*(arg_addr),*(arg_addr+1),*(arg_addr+2),*(arg_addr+3),*(arg_addr+4),*(arg_addr+5),*(arg_addr+6),*(arg_addr+7),*(arg_addr+8));
  

  return TRUE;
}


static gboolean test_method_handler_2(ContiExampleInterface *object, GVariant *arg_addr,gint arg_length, gpointer user_data)
{
  unsigned char byteArray[1024];

  int lengi=0;
  GVariantIter *iter;
  guchar data;

  GVariant* test=arg_addr;
  if(arg_addr!=NULL)
  {
      g_variant_get (arg_addr, "a(y)", &iter);

    while (g_variant_iter_loop (iter, "(y)", &data))
    {
      byteArray[lengi++] = data;
    }
    g_variant_iter_free (iter);
  }
  printf("test_method_handler_2 data is: %d %d %d %d %d %d %d %d %d
", byteArray,*(byteArray),*(byteArray+1),*(byteArray+2),*(byteArray+3),*(byteArray+4),*(byteArray+5),*(byteArray+6),*(byteArray+7),*(byteArray+8));
  

  return TRUE;
}


static gboolean test_method_handler_3(ContiExampleInterface *object, const GVariant *arg_addr,gint arg_length, gpointer user_data)
{
  unsigned char byteArray[20];

  int lengi=0;
  GVariantIter *iter_3;
  unsigned char data;
  if(arg_addr!=NULL)
  {  
    printf("start : 
");

    g_variant_get ((GVariant*)arg_addr, "ay", &iter_3);  
    printf("iter end : 
");

    while (g_variant_iter_loop (iter_3, "y", &data))
    {
      byteArray[lengi++] = data;
    }
    g_variant_iter_free (iter_3);
    printf("test_method_handler_2 data is: %d %d %d %d %d %d %d %d %d
", byteArray,*(byteArray),*(byteArray+1),*(byteArray+2),*(byteArray+3),*(byteArray+4),*(byteArray+5),*(byteArray+6),*(byteArray+7),*(byteArray+8));
  }
  else
  {
    printf("arg_addr NULL : 
");
  }

  return TRUE;
}
/////////////////////////////////////////////////////////////////////////////////////////
// Thread functions
/////////////////////////////////////////////////////////////////////////////////////////

static void *run(void *arg)
{
    // Start the Main Event Loop which manages all available sources of events
    g_main_loop_run( g_pLoop );
    
    return((void *)0);
}

static int thread_create()
{
    int err;
    pthread_t thr;

    err = pthread_create(&thr, NULL, run, NULL);

    if (err != 0)
    {
        printf("Can't create thread: %s
", strerror(err));
    }
    else
    {
        printf("New thread created: %s
", strerror(err));
    }

    return err;
}

static int init_global_var(void)
{
    int ret = 0;

    //ret = initCallbackArray(&g_method1_callback);
    //ret = initCallbackArray(&g_method2_callback);

    memset(&g_signal_callback, 0, sizeof(SIGNAL_CALLBACK_T));

    return ret;
}

static void print_version(void)
{
    printf("example wrapper version: (major: %d, minor: %d)
", dbusexampleclient_VERSION_MAJOR, dbusexampleclient_VERSION_MINOR);
}

INIT_RESULT_E initialize()
{
    INIT_RESULT_E ret;
    
    print_version();
    pthread_mutex_lock(&g_mutex);
    if (g_pProxcy == NULL)
    {
       // Initialize some global variables
       //init_global_var();
       // Start Dbus communication
       startDBusCommunication();
       // Create new thread
       thread_create();
       ret = INIT_SUCCESS;
    }
    else
    {
       g_print("initialize: Already initialized.
");
       ret = ALREADY_INITIALIZED;
    }
    pthread_mutex_unlock(&g_mutex);
    return ret;
}



void uninitialize()
{
    pthread_mutex_lock(&g_mutex);
    // Stop Dbus communication
    stopDBusCommunication();
    g_pProxcy = NULL;
    g_pLoop = NULL;
    g_pConnection = NULL;
    pthread_mutex_unlock(&g_mutex);
}

/////////////////////////////////////////////////////////////////////////////////////////
// Dbus communication functions
/////////////////////////////////////////////////////////////////////////////////////////
static int startDBusCommunication()
{
    int     iLoop      = 0;
    int     bRet       = TRUE;
    GError *pConnError = NULL;
    GError *pProxError = NULL;

    // Init for usage of "g" types
    g_type_init();

    g_print("startDBusCommunication: Client started.
");

    do
    {
        bRet = TRUE;
        ++iLoop;
        g_print("StartDBusCommunication: try %d.
", iLoop);

        // Create main loop, but do not start it.
        g_pLoop = g_main_loop_new(NULL, FALSE);

        // First step: Connect to dbus        
        g_pConnection = g_bus_get_sync(CONTI_GDBUS_EXAMPLE_BUS, NULL, &pConnError);

        if(pConnError == NULL)
        {
            // Second step: Try to get a connection to the given bus.
            g_pProxcy = conti_example_interface_proxy_new_sync(g_pConnection,
                                                   G_DBUS_PROXY_FLAGS_NONE,
                                                   CONTI_GDBUS_EXAMPLE_BUS_NAME,
                                                   CONTI_GDBUS_EXAMPLE_OBJECT_PATH,
                                                   NULL,
                                                   &pProxError);
            if (g_pProxcy == 0)
            {
                g_print("StartDBusCommunication: Failed to create proxy. Reason: %s.
", pProxError->message);
                g_error_free(pProxError);
                bRet = FALSE;
            }
        }
        else
        {
            g_print("StartDBusCommunication: Failed to connect to dbus. Reason: %s.
", pConnError->message);
            g_error_free(pConnError);
            bRet = FALSE;
        }

        if ( bRet == FALSE )
        {
          //wait 250 millisecs
          usleep( 250*1000 );
        }
    }
    while( bRet == FALSE );

    if( bRet == TRUE)
    {
        // Third step: Attach to dbus signals
        (void)g_signal_connect(g_pProxcy, "my-signal1", G_CALLBACK(My_Signal_1_Handler), NULL);
        (void)g_signal_connect(g_pProxcy, "my-signal2", G_CALLBACK(My_Signal_2_Handler), NULL);        
        (void)g_signal_connect(g_pProxcy, "test-method", G_CALLBACK(test_method_handler), NULL);
        (void)g_signal_connect(g_pProxcy, "test-method-2", G_CALLBACK(test_method_handler_2), NULL);
        (void)g_signal_connect(g_pProxcy, "test-method-3", G_CALLBACK(test_method_handler_3), NULL);


    }

    return (bRet);    
}

static int stopDBusCommunication()
{
    int bRet = FALSE;

    if (g_pLoop != 0)
    {
        g_main_loop_quit(g_pLoop);
        g_main_loop_unref(g_pLoop);
        g_pLoop = NULL;
        bRet = TRUE;
    }

    return (bRet);
}




void Signal1_Callback(const char* arg)
{
  printf("Main: ************************
");
  printf("Main:     Signal1 callback    
");
  printf("Main: ************************
");
  printf("ODC_Signal_1_Callback: Paramater value: %s.
", arg);
}

void Signal2_Callback(const int int_arg, const char *str_arg)
{
  printf("Main: ************************
");
  printf("Main:     Signal2 callback    
");
  printf("Main: ************************
");
  printf("ODC_Signal_2_Callback: Int value: %d, String value: %s
", int_arg, str_arg);
}

void Method1_Callback(const char *arg, const bool isFail, const void *userdata)
{
  int *p = (int*)userdata;
  printf("Main: ************************
");
  printf("Main:   Method1 callback(%d)  
", *p);
  printf("Main: ************************
");
  if (isFail)
  {
    printf("Method1Callback: method1 call fail.
");
  }
  else
  {
    printf("Method1Callback: return value: %s.
", arg);
  }
  
  return;
}

void Method2_Callback(const char *out_arg1, const int out_arg2, const bool isFail, const void *userdata)
{
  int *p = (int*)userdata;
  printf("Main: ************************
");
  printf("Main:   Method1 callback(%d)  
", *p);
  printf("Main: ************************
");
  if (isFail)
  {
    printf("Method2Callback: method2 call fails.
");
  }
  else
  {
    printf("Method2Callback: return value: (%s, %d).
", out_arg1, out_arg2);
  }
}

int main(void)
{
  SIGNAL_CALLBACK_T signal_callback;
  METHOD_CALLBACK_T method_callback;
  
  // Register signal callback function
  signal_callback.callback1 = Signal1_Callback;
  signal_callback.callback2 = Signal2_Callback;
  registerSignalCallback(&signal_callback);
  method_callback.callback1 = Method1_Callback;
  method_callback.callback2 = Method2_Callback;
  registerMethodCallback(&method_callback);
  
  initialize();
  usleep(2000*1000);

  #if 0
  // synchronize call the function "MyMethod1" defined in xcom.contiautomotive.Gdbus.Example.xml file
  g_printf("Main: ************************
");
  g_printf("Main: Synchronize call method1
");
  g_printf("Main: ************************
");
  gchar * sync_call_method1_arg = "method1 Synchronize call";
  gchar * sync_call_method1_out = NULL;
  GError *sync_call_method1_error =NULL;
  My_method_1(sync_call_method1_arg, &sync_call_method1_out, &sync_call_method1_error);
  if (sync_call_method1_error == NULL)
  {
    g_printf("My_method_1: Method called. Return value: %s.
", sync_call_method1_out);
    g_free(sync_call_method1_out);
  }
  else
  {
    g_printf("My_method_1: Failed to call method. Reason: %s.
", sync_call_method1_error->message);
    g_error_free(sync_call_method1_error);
  }
  #endif
  // Asynchornize call the function "MyMethod1" defined in xcom.contiautomotive.Gdbus.Example.xml file
  /*
  printf("Main: ************************
");
  printf("Main: Asynchronize call method1
");
  printf("Main: ************************
");
  char * async_call_method1_arg = "1st method1 Asynchronize call";
  int tmp1 = 1;
  My_method_1_Async(async_call_method1_arg, (void*)&tmp1);
  async_call_method1_arg = "2nd method1 Asynchronize call";
  int tmp2 = 2;
  My_method_1_Async(async_call_method1_arg, (void*)&tmp2);
  async_call_method1_arg = "3rd method1 Asynchronize call";
  int tmp3 = 3;
  My_method_1_Async(async_call_method1_arg, (void*)&tmp3);
  async_call_method1_arg = "4th method1 Asynchronize call";
  int tmp4 = 4;
  My_method_1_Async(async_call_method1_arg, (void*)&tmp4);
  async_call_method1_arg = "5th method1 Asynchronize call";
  int tmp5 = 5;
  My_method_1_Async(async_call_method1_arg, (void*)&tmp5);
  async_call_method1_arg = "6th method1 Asynchronize call";
  int tmp6 = 6;
  My_method_1_Async(async_call_method1_arg, (void*)&tmp6);
  async_call_method1_arg = "7th method1 Asynchronize call";
  int tmp7 = 7;
  My_method_1_Async(async_call_method1_arg, (void*)&tmp7);
  async_call_method1_arg = "8th method1 Asynchronize call";
  int tmp8 = 8;
  My_method_1_Async(async_call_method1_arg, (void*)&tmp8);
  async_call_method1_arg = "9th method1 Asynchronize call";
  int tmp9 = 9;
  My_method_1_Async(async_call_method1_arg, (void*)&tmp9);
  async_call_method1_arg = "10th method1 Asynchronize call";
  int tmp10 = 10;
  My_method_1_Async(async_call_method1_arg, (void*)&tmp10);
  async_call_method1_arg = "11th method1 Asynchronize call";
  int tmp11 = 11;
  My_method_1_Async(async_call_method1_arg, (void*)&tmp11);
  async_call_method1_arg = "12th method1 Asynchronize call";
  int tmp12 = 12;
  My_method_1_Async(async_call_method1_arg, (void*)&tmp12);
  */
  usleep(2000*1000);
  #if 0
  // synchronize call the function "MyMethod2" defined in xcom.contiautomotive.Gdbus.Example.xml files
  g_printf("Main: ************************
");
  g_printf("Main: Synchronize call method2
");
  g_printf("Main: ************************
");
  GError *sync_call_method2_error =NULL;
  gint sync_call_method1_arg1 = 12;
  gint sync_call_method1_arg2 = 1234;
  gchar *sync_call_method1_out1 = NULL;
  gint sync_call_method1_out2 = 0;
  My_method_2(sync_call_method1_arg1, sync_call_method1_arg2, &sync_call_method1_out1, &sync_call_method1_out2, &sync_call_method2_error);
  if (sync_call_method2_error == NULL)
  {
    g_printf("My_method_2: Method called. Return value: (%s, %d).
", sync_call_method1_out1, sync_call_method1_out2);
    g_free(sync_call_method1_out1);
  }
  else
  {
    g_printf("My_method_2: Failed to call method. Reason: %s.
", sync_call_method1_error->message);
    g_error_free(sync_call_method1_error);
  }
  #endif
  // Asynchronize call the function "MyMethod2" defined in xcom.contiautomotive.Gdbus.Example.xml files
  printf("Main: ************************
");
  printf("Main: Asynchronize call method2
");
  printf("Main: ************************
");
  int async_call_method2_arg1 = 10;
  int async_call_method2_arg2 = 32;
  int tmp13 = 1;
  My_method_2_Async(async_call_method2_arg1, async_call_method2_arg2, (void*)&tmp13);
  
  usleep(2000*1000);
  
  uninitialize();
  
  return 0;
}
View Code

目前存在一个问题,就是用方法3强制转换后,client解析出错,但是同样的解析代码我放在server端去解析缺没问题...没找到问题点...知道的告诉我下...过几天再来看也许就能发现了...

我感觉用第二种方法比较好,稳妥,以后如果需要传输数据,我应该也会直接用第二种方法,把数据组合。

举个例子:比较复杂点如

<arg direction="out" name="sinks" type="a(ss(ii))">

    // Type: a(ss(ii))
    GVariant* sinks = NULL;
    GVariantBuilder *builder;

    builder = g_variant_builder_new (G_VARIANT_TYPE ("a(ss(ii))"));

    // Mic
    g_variant_builder_add (builder, "(ss(ii))", conn::hfc::SK_HFC_MIC.c_str(), "conn/hfcMic", am::A_AVAILABLE, am::AR_GENIVI_NEWMEDIA);

    sinks = g_variant_new ("a(ss(ii))", builder);
    g_variant_builder_unref (builder);

    iaudio_sink_complete_get_sinks ( object, invocation, sinks, am::E_OK);
View Code
原文地址:https://www.cnblogs.com/jlmgary/p/6812077.html