I would like to transmit a data array from one application to the other via DBus.
My code as below:
server.c:
/* server.c */
#include <dbus/dbus.h>
#include <stdbool.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
DBusHandlerResult filter_func(DBusConnection *connection,
DBusMessage *message, void *usr_data)
{
DBusMessage *reply;
dbus_bool_t handled = false;
char *pReadData;
unsigned char len;
unsigned char i;
DBusError dberr;
dbus_error_init(&dberr);
printf("pReadData = %x\n", (unsigned int)pReadData);
if(FALSE == dbus_message_get_args(message, &dberr, DBUS_TYPE_ARRAY,
DBUS_TYPE_BYTE, &pReadData, &len, DBUS_TYPE_INVALID) && 0 != len)
{
//printf("len = %d\n");
//printf("receiver data error\n");
return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
}
if(0 == len)
return DBUS_HANDLER_RESULT_HANDLED;
printf("len = %d, ", len);
for( i = 0; i < len; i++)
printf("%#2x ", (unsigned char)pReadData[i]);
printf("\n");
handled = true;
printf("pReadData = %x\n", (unsigned int)pReadData);
/*if one free pReadData, it will crash!*/
//dbus_free_string_array((char**)&pReadData);
return (handled ? DBUS_HANDLER_RESULT_HANDLED :
DBUS_HANDLER_RESULT_NOT_YET_HANDLED);
}/*filter_func*/
int main(int argc, char *argv[])
{
DBusError dberr;
DBusConnection *dbconn;
dbus_error_init(&dberr);
dbconn = dbus_bus_get(DBUS_BUS_SESSION, &dberr);
if (!dbus_connection_add_filter(dbconn, filter_func, NULL, NULL)) {
return -1;
}
dbus_bus_add_match(dbconn, "type='signal',interface='gaiger.Drstein.Demonstration'", &dberr);
while(dbus_connection_read_write_dispatch(dbconn, -1)) {
/* loop */
}
return 0;
}/*main*/
And client.c
#include <dbus/dbus.h>
#include <stdbool.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
int db_send(DBusConnection *dbconn)
{
DBusMessage *dbmsg;
char *pSendData;
unsigned char len;
unsigned char i;
pSendData = (char *)malloc(256);
dbmsg = dbus_message_new_signal("/client/signal/Object",
"gaiger.Drstein.Demonstration", "Test");
len = 6;
for(i = 0; i < len; i++)
pSendData[i] = (unsigned char)i;
if (!dbus_message_append_args(dbmsg, DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE,
&pSendData, len, DBUS_TYPE_INVALID))
{
return -1;
}
if (!dbus_connection_send(dbconn, dbmsg, NULL)) {
return -1;
}
dbus_connection_flush(dbconn);
printf("send message : len = %d, ", len );
for( i = 0; i < len; i++)
printf("%#x ", (unsigned char)pSendData[i]);
printf("\n");
dbus_message_unref(dbmsg);
free(pSendData);
return 0;
}/**/
int main(int argc, char *argv[])
{
unsigned int i;
DBusError dberr;
DBusConnection *dbconn;
dbus_error_init(&dberr);
dbconn = dbus_bus_get(DBUS_BUS_SESSION, &dberr);
#if(1)
for(i = 0; i < 3; i++)
db_send(dbconn);
#else
while(dbus_connection_read_write_dispatch(dbconn, -1)) {
db_send(dbconn);
}
#endif
dbus_connection_unref(dbconn);
return 0;
}
The code works in Ubuntu 14.4, x86-64, but it crash in printing received data in Fedora 21, x86-32, virtual machine.
For the line :
if(FALSE == dbus_message_get_args(message, &dberr, DBUS_TYPE_ARRAY,
DBUS_TYPE_BYTE, &pReadData, &len, DBUS_TYPE_INVALID) && 0 != len)
I know the pointer pReadData would be allocated by dbus itself, the address value after this line is 0x90000 in Fedora 21, it is very odd number.
How should I do to avoid crash but print received data values in Fedora 21 x86 32bit?
Thank your help.
答案 0 :(得分:1)
dbus_message_get_args的文档说明dbus_message_iter_get_fixed_array,我们看到len
参数是指向整数的指针(因为在DBus“数组中有最大长度定义为2到26次幂或67108864(64 MiB)。“)但是您传递的指针指向unsigned char
。在服务器的第15行使用int len;
。
此外,您不应该假设int
和指针的大小相同,而是使用long
来打印指针。
printf("pReadData = %lx\n", (unsigned long)pReadData);