• 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
  • 相关阅读:
    Android 程序员不得不收藏的个人博客(持续更新...)
    硬核讲解 Jetpack 之 LifeCycle 源码篇
    秉心说,不一样的 2019
    秉心说 2019 博文合集
    庖丁解牛 Activity 启动流程
    Jetpack Compse 实战 —— 全新的开发体验
    Box 黑科技 —— 支持手机端反编译 !
    “无处不在” 的系统核心服务 —— ActivityManagerService 启动流程解析
    如何正确的在 Android 上使用协程 ?
    【Medium 万赞好文】ViewModel 和 LIveData:模式 + 反模式
  • 原文地址:https://www.cnblogs.com/jlmgary/p/6812077.html
Copyright © 2020-2023  润新知