最近阅读了Redis6.2源码,添加了一些注释,感兴趣的同学可以看下。
https://github.com/neohope/NeoRedisSrc
Category Archives: C
编译Wkhtmltopdf
1、首先下载源码
git clone https: //github .com /wkhtmltopdf/wkhtmltopdf .git D:\GitHub\wkhtmltopdf git clone https: //github .com /wkhtmltopdf/qt .git D:\GitHub\wkhtmltopdf\qt |
2、安装下面几个软件
VS2013
Python2.7
ActivePerl
NSIS
3、初始化环境变量
set GIT_HOME=C:\Program Files\Git set NSIS_HOME=C:\NeoLanguages\NSIS set PYTHON_HOME=C:\NeoLanguages\Python27_x86 set PERL_HOME=C:\NeoLanguages\Perl set PATH=%GIT_HOME%\bin;%PYTHON_HOME%;%PERL_HOME%\bin;%NSIS_HOME%;%PATH% @call C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\vcvarsall.bat x86 |
4、编译
python scripts\build.py msvc2013-win32 |
PS:
如果编译失败,一般是由于依赖包的网站无法方位导致的,你懂的。
这个时候,打开build.py文件,找到DEPENDENT_LIBS,自备梯子,下载后直接放到static-build路径下就好了。
posix_memalign函数在Windows下的实现
posix_memalign函数主要用于申请内存时,做内存对齐使用,Windows下对应的函数为_aligned_malloc,但两者的参数有一定区别:
int posix_memalign( void **memptr, size_t alignment, size_t size); void * _aligned_malloc( size_t size, size_t alignment); |
从stackoverflow上,找到了两种实现方式,对于第一种,我只能说,佩服佩服。
1、最简练的实现方式
#define posix_memalign(p, a, s) (((*(p)) = _aligned_malloc((s), (a))), *(p) ?0 :errno) |
2、比较稳妥的实现方式
#ifdef _WIN32 static int check_align( size_t align) { for ( size_t i = sizeof ( void *); i != 0; i *= 2) if (align == i) return 0; return EINVAL; } int posix_memalign( void **ptr, size_t align, size_t size) { if (check_align(align)) return EINVAL; int saved_errno = errno ; void *p = _aligned_malloc(size, align); if (p == NULL) { errno = saved_errno; return ENOMEM; } *ptr = p; return 0; } #endif |
CPP实现CORBA静态绑定(八)
- CORBA基本架构
- IDL文件编写
- CPP示例实现(上)
- CPP示例实现(下)
- C示例实现(IOR+NS上)
- C示例实现(IOR+NS下)
- C示例实现(IOR上)
- C示例实现(IOR下)
然后完成客户端部分:
Hi-client-ior.c
#include <assert.h> #include <signal.h> #include <stdio.h> #include <stdlib.h> #include <orbit/orbit.h> #include "Hi.h" /* Usage: ./hi-client_ns */ /** * test for exception */ static gboolean raised_exception(CORBA_Environment *ev) { return ((ev)->_major != CORBA_NO_EXCEPTION); } /** * in case of any exception this macro will abort the process */ static void abort_if_exception(CORBA_Environment *ev, const char * mesg) { if (raised_exception (ev)) { g_error ( "%s %s" , mesg, CORBA_exception_id (ev)); CORBA_exception_free (ev); abort (); } } /* * main */ int main( int argc, char * argv[]) { CORBA_ORB orb=CORBA_OBJECT_NIL; CORBA_Environment ev; HiCorba_Hi service = CORBA_OBJECT_NIL; //init orb g_print( "\nClient>starting client..." ); g_print( "\nClient>creating and initializing the ORB" ); CORBA_exception_init(&ev); abort_if_exception(&ev, "CORBA_exception_init failed" ); orb=CORBA_ORB_init(&argc,argv, "orbit-local-orb" ,&ev); abort_if_exception(&ev, "CORBA_ORB_init failed" ); // read name_service ior from ns.ior CORBA_char filename[] = "service.ior" ; FILE *file = NULL; g_print( "\nClient>reading the file '%s'" ,filename); if ((file= fopen (filename, "r" ))==NULL) g_error ( "could not open '%s'" , filename); gchar objref[1024]; fscanf (file, "%s" , &objref); g_print( "\nClient>getting the 'IOR' - from the file '%s'" ,filename); g_print( "\nClient>the IOR is '%s'" ,objref); service = (HiCorba_Hi)CORBA_ORB_string_to_object(orb,objref,&ev); abort_if_exception(&ev, "CORBA_ORB_string_to_object 'NameService IOR' failed" ); // invoke service g_print( "\nClient>calling the Hi service..." ); CORBA_char *msg=HiCorba_Hi_sayHiTo(service, "neohope" , &ev); abort_if_exception(&ev, "HiCorba_Hi_sayHiTo failed" ); g_print( "\nClient>server returned the following message: %s\n" , msg); CORBA_Object_release(service, &ev); abort_if_exception(&ev, "release failed" ); if (orb != CORBA_OBJECT_NIL) { /* going to destroy orb.. */ CORBA_ORB_destroy(orb, &ev); abort_if_exception(&ev, "destroy failed" ); } } |
MakeClient
CC = gcc CFLAGS = -c -g -pthread -D_REENTRANT -DORBIT2=1 \ -I /usr/include/orbit-2 .0 \ -I /usr/include/glib-2 .0 \ -I /usr/lib/x86_64-linux-gnu/glib-2 .0 /include LDFLAGS = -Wl,-- export -dynamic -lORBit-2 -lORBitCosNaming-2 -lgmodule-2.0 \ -ldl -lgobject-2.0 -lgthread-2.0 -lpthread -lglib-2.0 -lm \ -L /usr/lib ORBIT_IDL= /usr/bin/orbit-idl-2 all : Hi-client-ior.bin Hi-client-ior.bin : Hi-common.o Hi-stubs.o Hi-client-ior.o $(CC) $(LDFLAGS) Hi-common.o Hi-stubs.o Hi-client-ior.o -o Hi-client-ior.bin %.o : %.c $(CC) $(CFLAGS) $< -o $@ nidl : Hi.idl $(ORBIT_IDL) Hi.idl $(ORBIT_IDL) --skeleton-impl Hi.idl clean: rm -rf *.bin rm -rf *.o |
编译
Make -f MakeClient |
运行
#首先运行orbd orbd -ORBInitialPort 1900 #然后运行server . /Hi-server-ior .bin Server>starting server... Server>creating and initializing the ORB Server>getting reference to RootPOA Server>activating the POA Manager Server>creating the servant Server>writing the file 'service.ior' Server>writing the IOR to file 'service.ior' Server>running the orb... Server>server is returning: Hi, neohope ! #然后运行client . /Hi-client-ior .bin Client>starting client... Client>creating and initializing the ORB Client>reading the file 'service.ior' Client>getting the 'IOR' - from the file 'service.ior' Client>the IOR is 'IOR:010000001300000049444c3a4869436f7262612f48693a312e300000030000000054424f580000000101020005000000554e4958000000000a0000006c6f63616c686f73740000002d0000002f746d702f6f726269742d6e656f686f70652f6c696e632d316235362d302d376663653334336261303164360000000000000000caaedfba58000000010102002d0000002f746d702f6f726269742d6e656f686f70652f6c696e632d316235362d302d37666365333433626130316436000000001c00000000000000dbcce0b85e73a828c02b2828282828280100000060aa3a1a01000000480000000100000002000000050000001c00000000000000dbcce0b85e73a828c02b2828282828280100000060aa3a1a01000000140000000100000001000105000000000901010000000000' Client>calling the Hi service... Client>server returned the following message: Hi, neohope ! |
CPP实现CORBA静态绑定(七)
- CORBA基本架构
- IDL文件编写
- CPP示例实现(上)
- CPP示例实现(下)
- C示例实现(IOR+NS上)
- C示例实现(IOR+NS下)
- C示例实现(IOR上)
- C示例实现(IOR下)
在linux系统下,有很多开源的CORBA通讯框架,在C的示例中,使用了orbit的框架。
如我用的是Debian系统,可以直接安装:
apt-get install orbit2 apt-get install liborbit2-dev |
安装后,可以通过工具orb-rdl-2从idl文件生成需要的stubs及skeletons接口代码:
#该命令会生成文件:Hi.h、Hi-common.c、Hi-skels.c、Hi-stubs.c orbit-idl-2 Hi.idl |
可以通过工具orb-rdl-2从idl文件生成服务端代码:
#该命令会生成模板文件:Hi-skelimpl.c orbit-idl-2 --skeleton-impl Hi.idl |
首先完成服务端部分:
Hi-server-ior.c
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <signal.h> #include <orbit/orbit.h> #include "Hi.h" #include "Hi-skelimpl.c" /* ./Hi-server_ns -ORBInitRef NameService=[string of IOR of NameService] */ /** * test for exception */ static gboolean raised_exception(CORBA_Environment *ev) { return ((ev)->_major != CORBA_NO_EXCEPTION); } /** * in case of any exception this macro will abort the process */ static void abort_if_exception(CORBA_Environment *ev, const char * mesg) { if (raised_exception (ev)) { g_error ( "%s %s" , mesg, CORBA_exception_id (ev)); CORBA_exception_free (ev); abort (); } } /* * main */ int main ( int argc, char *argv[]) { PortableServer_POA poa; HiCorba_Hi servant = CORBA_OBJECT_NIL; CORBA_ORB orb=CORBA_OBJECT_NIL; CORBA_Environment ev; // init ORB g_print( "\nServer>starting server..." ); g_print( "\nServer>creating and initializing the ORB" ); CORBA_exception_init(&ev); abort_if_exception(&ev, "CORBA_exception_init failed" ); orb=CORBA_ORB_init(&argc,argv, "orbit-local-orb" ,&ev); abort_if_exception(&ev, "CORBA_ORB_init failed" ); // activate POA g_print( "\nServer>getting reference to RootPOA" ); poa= (PortableServer_POA) CORBA_ORB_resolve_initial_references(orb, "RootPOA" ,&ev); abort_if_exception(&ev, "CORBA_ORB_resolve_initial 'RootPOA' failed" ); g_print( "\nServer>activating the POA Manager" ); PortableServer_POAManager_activate(PortableServer_POA__get_the_POAManager(poa, &ev),&ev); abort_if_exception(&ev, "POA_activate failed" ); // create servant g_print( "\nServer>creating the servant" ); servant = impl_HiCorba_Hi__create (poa, &ev); abort_if_exception(&ev, "impl_HiCorba_Hi__create failed" ); // read name_service ior from ns.ior CORBA_char filename[] = "service.ior" ; FILE *file = NULL; g_print( "\nServer>writing the file '%s'" ,filename); if ((file= fopen (filename, "w" ))==NULL) g_error ( "could not open '%s'\n" , filename); gchar *objref = CORBA_ORB_object_to_string (orb, servant, &ev); abort_if_exception(&ev, "CORBA_ORB_object_to_string' failed" ); fprintf (file, "%s" ,objref); fflush (file); fclose (file); g_print( "\nServer>writing the IOR to file '%s'" ,filename); // start g_print( "\nServer>running the orb..." ); CORBA_ORB_run(orb,&ev); abort_if_exception(&ev, "ORB_run failed" ); } |
Hi-skelimpl.c
/* This is a template file generated by command */ /* orbit-idl-2 --skeleton-impl Hi.idl */ /* User must edit this file, inserting servant */ /* specific code between markers. */ #include <stdlib.h> #include <stdio.h> #include "Hi.h" /*** App-specific servant structures ***/ #if !defined(_typedef_impl_POA_HiCorba_Hi_) #define _typedef_impl_POA_HiCorba_Hi_ 1 typedef struct { POA_HiCorba_Hi servant; PortableServer_POA poa; /* ------ add private attributes here ------ */ /* ------ ---------- end ------------ ------ */ } impl_POA_HiCorba_Hi; #endif /*** Implementation stub prototypes ***/ #if !defined(_decl_impl_HiCorba_Hi__destroy_) #define _decl_impl_HiCorba_Hi__destroy_ 1 static void impl_HiCorba_Hi__destroy(impl_POA_HiCorba_Hi *servant, CORBA_Environment *ev); #endif #if !defined(_decl_impl_HiCorba_Hi_sayHiTo_) #define _decl_impl_HiCorba_Hi_sayHiTo_ 1 static CORBA_string impl_HiCorba_Hi_sayHiTo(impl_POA_HiCorba_Hi *servant, const CORBA_char * someone, CORBA_Environment *ev); #endif #if !defined(_decl_impl_HiCorba_Hi_add_) #define _decl_impl_HiCorba_Hi_add_ 1 static CORBA_long impl_HiCorba_Hi_add(impl_POA_HiCorba_Hi *servant, const CORBA_long numa, const CORBA_long numb, CORBA_Environment *ev); #endif #if !defined(_decl_impl_HiCorba_Hi_shutdown_) #define _decl_impl_HiCorba_Hi_shutdown_ 1 static void impl_HiCorba_Hi_shutdown(impl_POA_HiCorba_Hi *servant, CORBA_Environment *ev); #endif /*** epv structures ***/ #if !defined(_impl_HiCorba_Hi_base_epv_) #define _impl_HiCorba_Hi_base_epv_ 1 static PortableServer_ServantBase__epv impl_HiCorba_Hi_base_epv = { NULL, /* _private data */ (gpointer) & impl_HiCorba_Hi__destroy, /* finalize routine */ NULL, /* default_POA routine */ }; #endif #if !defined(_impl_HiCorba_Hi_epv_) #define _impl_HiCorba_Hi_epv_ 1 static POA_HiCorba_Hi__epv impl_HiCorba_Hi_epv = { NULL, /* _private */ (gpointer)&impl_HiCorba_Hi_sayHiTo, (gpointer)&impl_HiCorba_Hi_add, (gpointer)&impl_HiCorba_Hi_shutdown, }; #endif /*** vepv structures ***/ #if !defined(_impl_HiCorba_Hi_vepv_) #define _impl_HiCorba_Hi_vepv_ 1 static POA_HiCorba_Hi__vepv impl_HiCorba_Hi_vepv = { &impl_HiCorba_Hi_base_epv, &impl_HiCorba_Hi_epv, }; #endif /*** Stub implementations ***/ #if !defined(_impl_HiCorba_Hi__create_) #define _impl_HiCorba_Hi__create_ 1 static HiCorba_Hi impl_HiCorba_Hi__create(PortableServer_POA poa, CORBA_Environment *ev) { HiCorba_Hi retval; impl_POA_HiCorba_Hi *newservant; PortableServer_ObjectId *objid; newservant = g_new0(impl_POA_HiCorba_Hi, 1); newservant->servant.vepv = &impl_HiCorba_Hi_vepv; newservant->poa = (PortableServer_POA) CORBA_Object_duplicate((CORBA_Object)poa, ev); POA_HiCorba_Hi__init((PortableServer_Servant)newservant, ev); /* Before servant is going to be activated all * private attributes must be initialized. */ /* ------ init private attributes here ------ */ /* ------ ---------- end ------------- ------ */ objid = PortableServer_POA_activate_object(poa, newservant, ev); CORBA_free(objid); retval = PortableServer_POA_servant_to_reference(poa, newservant, ev); return retval; } #endif #if !defined(_impl_HiCorba_Hi__destroy_) #define _impl_HiCorba_Hi__destroy_ 1 static void impl_HiCorba_Hi__destroy(impl_POA_HiCorba_Hi *servant, CORBA_Environment *ev) { CORBA_Object_release ((CORBA_Object) servant->poa, ev); /* No further remote method calls are delegated to * servant and you may free your private attributes. */ /* ------ free private attributes here ------ */ /* ------ ---------- end ------------- ------ */ POA_HiCorba_Hi__fini((PortableServer_Servant)servant, ev); g_free (servant); } #endif #if !defined(_impl_HiCorba_Hi_sayHiTo_) #define _impl_HiCorba_Hi_sayHiTo_ 1 static CORBA_string impl_HiCorba_Hi_sayHiTo(impl_POA_HiCorba_Hi *servant, const CORBA_char * someone, CORBA_Environment *ev) { CORBA_string retval = CORBA_string_alloc(512); /* ------ insert method code here ------ */ sprintf (retval, "Hi, %s !" ,someone); g_print( "\nServer>server is returning: %s" ,retval); /* ------ ---------- end ------------ ------ */ return retval; } #endif #if !defined(_impl_HiCorba_Hi_add_) #define _impl_HiCorba_Hi_add_ 1 static CORBA_long impl_HiCorba_Hi_add(impl_POA_HiCorba_Hi *servant, const CORBA_long numa, const CORBA_long numb, CORBA_Environment *ev) { CORBA_long retval; /* ------ insert method code here ------ */ retval = numa+numb; /* ------ ---------- end ------------ ------ */ return retval; } #endif #if !defined(_impl_HiCorba_Hi_shutdown_) #define _impl_HiCorba_Hi_shutdown_ 1 static CORBA_ORB _neo_ORB = CORBA_OBJECT_NIL; static HiCorba_Hi _neo_servant = CORBA_OBJECT_NIL; static void set_NEO_ORB(CORBA_ORB theORB, HiCorba_Hi theServant) { _neo_ORB = theORB; _neo_servant = theServant; } static void impl_HiCorba_Hi_shutdown(impl_POA_HiCorba_Hi *servant, CORBA_Environment *ev) { /* ------ insert method code here ------ */ if (_neo_ORB==CORBA_OBJECT_NIL || _neo_servant == CORBA_OBJECT_NIL) return ; // g_print( "\nServer>executing the release" ); CORBA_Object_release(_neo_servant,ev); if ((ev)->_major != CORBA_NO_EXCEPTION){ g_error ( "%s %s" , "Object_release failed" , CORBA_exception_id (ev)); CORBA_exception_free (ev); abort (); } // g_print( "\nServer>executing the shutdown" ); CORBA_ORB_shutdown(_neo_ORB, CORBA_FALSE, ev); if ((ev)->_major != CORBA_NO_EXCEPTION){ g_error ( "%s %s" , "shutdown failed" , CORBA_exception_id (ev)); CORBA_exception_free (ev); abort (); } exit (0); /* ------ ---------- end ------------ ------ */ } #endif |
MakeServer
CC = gcc CFLAGS = -c -g -pthread -D_REENTRANT -DORBIT2=1 \ -I /usr/include/orbit-2 .0 \ -I /usr/include/glib-2 .0 \ -I /usr/lib/x86_64-linux-gnu/glib-2 .0 /include LDFLAGS = -Wl,-- export -dynamic -lORBit-2 -lORBitCosNaming-2 -lgmodule-2.0 \ -ldl -lgobject-2.0 -lgthread-2.0 -lpthread -lglib-2.0 -lm \ -L /usr/lib ORBIT_IDL= /usr/bin/orbit-idl-2 all : Hi-server-ior.bin Hi-server-ior.bin : Hi-common.o Hi-skelimpl.o Hi-skels.o Hi-server-ior.o $(CC) $(LDFLAGS) Hi-common.o Hi-skelimpl.o Hi-skels.o Hi-server-ior.o -o Hi-server-ior.bin %.o : %.c $(CC) $(CFLAGS) $< -o $@ nidl : Hi.idl $(ORBIT_IDL) Hi.idl $(ORBIT_IDL) --skeleton-impl Hi.idl clean: rm -rf *.bin rm -rf *.o |
编译
make -f MakeServer |
CPP实现CORBA静态绑定(六)
- CORBA基本架构
- IDL文件编写
- CPP示例实现(上)
- CPP示例实现(下)
- C示例实现(IOR+NS上)
- C示例实现(IOR+NS下)
- C示例实现(IOR上)
- C示例实现(IOR下)
首先完成客户端部分:
Hi-client-ns.c
#include <assert.h> #include <signal.h> #include <stdio.h> #include <stdlib.h> #include <orbit/orbit.h> #include <ORBitservices/CosNaming.h> #include <ORBitservices/CosNaming_impl.h> #include "Hi.h" /* Usage: ./hi-client_ns */ /** * test for exception */ static gboolean raised_exception(CORBA_Environment *ev) { return ((ev)->_major != CORBA_NO_EXCEPTION); } /** * in case of any exception this macro will abort the process */ static void abort_if_exception(CORBA_Environment *ev, const char * mesg) { if (raised_exception (ev)) { g_error ( "%s %s" , mesg, CORBA_exception_id (ev)); CORBA_exception_free (ev); abort (); } } /* * main */ int main( int argc, char * argv[]) { CORBA_ORB orb=CORBA_OBJECT_NIL; CORBA_Environment ev; CosNaming_NamingContext ns =CORBA_OBJECT_NIL; HiCorba_Hi service = CORBA_OBJECT_NIL; CORBA_char name_service[]= "Hi" ; CosNaming_NameComponent path[1]={name_service, "" }; CosNaming_Name name={1,1,path,CORBA_FALSE}; //init orb g_print( "\nClient>starting client..." ); g_print( "\nClient>creating and initializing the ORB" ); CORBA_exception_init(&ev); abort_if_exception(&ev, "CORBA_exception_init failed" ); orb=CORBA_ORB_init(&argc,argv, "orbit-local-orb" ,&ev); abort_if_exception(&ev, "CORBA_ORB_init failed" ); // read name_service ior from ns.ior CORBA_char filename[] = "ns.ior" ; FILE *file = NULL; g_print( "\nClient>reading the file '%s'" ,filename); if ((file= fopen (filename, "r" ))==NULL) g_error ( "could not open '%s'" , filename); gchar objref[1024]; fscanf (file, "%s" , &objref); g_print( "\nClient>getting the root naming context 'NameService' - from the file '%s'" ,filename); g_print( "\nClient>the root naming context ior is '%s'" ,objref); ns = (CosNaming_NamingContext)CORBA_ORB_string_to_object(orb,objref,&ev); //free (objref); abort_if_exception(&ev, "CORBA_ORB_string_to_object 'NameService IOR' failed" ); //resolve object reference g_print( "\nClient>Resolving the object reference in naming '%s'" ,name_service); service=CosNaming_NamingContext_resolve(ns,&name,&ev); abort_if_exception(&ev, "resolve failed" ); // invoke service g_print( "\nClient>calling the Hi service..." ); CORBA_char *msg=HiCorba_Hi_sayHiTo(service, "neohope" , &ev); abort_if_exception(&ev, "HiCorba_Hi_sayHiTo failed" ); g_print( "\nClient>server returned the following message: %s\n" , msg); CORBA_Object_release(service, &ev); abort_if_exception(&ev, "release failed" ); if (orb != CORBA_OBJECT_NIL) { /* going to destroy orb.. */ CORBA_ORB_destroy(orb, &ev); abort_if_exception(&ev, "destroy failed" ); } } |
MakeClient
CC = gcc CFLAGS = -c -g -pthread -D_REENTRANT -DORBIT2=1 \ -I /usr/include/orbit-2 .0 \ -I /usr/include/glib-2 .0 \ -I /usr/lib/x86_64-linux-gnu/glib-2 .0 /include LDFLAGS = -Wl,-- export -dynamic -lORBit-2 -lORBitCosNaming-2 -lgmodule-2.0 \ -ldl -lgobject-2.0 -lgthread-2.0 -lpthread -lglib-2.0 -lm \ -L /usr/lib ORBIT_IDL= /usr/bin/orbit-idl-2 all : Hi-client-ns.bin Hi-client-ns.bin : Hi-common.o Hi-stubs.o Hi-client-ns.o $(CC) $(LDFLAGS) Hi-common.o Hi-stubs.o Hi-client-ns.o -o Hi-client-ns.bin %.o : %.c $(CC) $(CFLAGS) $< -o $@ nidl : Hi.idl $(ORBIT_IDL) Hi.idl $(ORBIT_IDL) --skeleton-impl Hi.idl clean: rm -rf *.bin rm -rf *.o |
编译
make -f MakeClient |
然后是运行
#首先运行orbd orbd -ORBInitialPort 1900 #然后运行nameservice orbit-name-server-2 > ns.ior #然后运行server . /Hi-server-ns .bin Server>starting server... Server>creating and initializing the ORB Server>getting reference to RootPOA Server>activating the POA Manager Server>creating the servant Server>reading the file 'ns.ior' Server>getting the root naming context 'NameService' - from the file 'ns.ior' Server>the root naming context ior is 'IOR:010000002b00000049444c3a6f6d672e6f72672f436f734e616d696e672f4e616d696e67436f6e746578744578743a312e300000030000000054424f580000000101020005000000554e4958000000000a0000006c6f63616c686f73740000002d0000002f746d702f6f726269742d6e656f686f70652f6c696e632d313735302d302d346431323731616531616661390000000000000000caaedfba58000000010102002d0000002f746d702f6f726269742d6e656f686f70652f6c696e632d313735302d302d34643132373161653161666139000000001c00000000000000d4d2dcc0a89f68a8c02b28282828282801000000eaaf213d01000000480000000100000002000000050000001c00000000000000d4d2dcc0a89f68a8c02b28282828282801000000eaaf213d01000000140000000100000001000105000000000901010000000000' Server>binding the object reference in naming with name 'Hi' Server>running the orb... Server>server is returning: Hi, neohope ! #然后运行client . /Hi-client-ns .bin Client>starting client... Client>creating and initializing the ORB Client>reading the file 'ns.ior' Client>getting the root naming context 'NameService' - from the file 'ns.ior' Client>the root naming context ior is 'IOR:010000002b00000049444c3a6f6d672e6f72672f436f734e616d696e672f4e616d696e67436f6e746578744578743a312e300000030000000054424f580000000101020005000000554e4958000000000a0000006c6f63616c686f73740000002d0000002f746d702f6f726269742d6e656f686f70652f6c696e632d313735302d302d346431323731616531616661390000000000000000caaedfba58000000010102002d0000002f746d702f6f726269742d6e656f686f70652f6c696e632d313735302d302d34643132373161653161666139000000001c00000000000000d4d2dcc0a89f68a8c02b28282828282801000000eaaf213d01000000480000000100000002000000050000001c00000000000000d4d2dcc0a89f68a8c02b28282828282801000000eaaf213d01000000140000000100000001000105000000000901010000000000' Client>Resolving the object reference in naming 'Hi' Client>calling the Hi service... Client>server returned the following message: Hi, neohope ! |
CPP实现CORBA静态绑定(五)
- CORBA基本架构
- IDL文件编写
- CPP示例实现(上)
- CPP示例实现(下)
- C示例实现(IOR+NS上)
- C示例实现(IOR+NS下)
- C示例实现(IOR上)
- C示例实现(IOR下)
在linux系统下,有很多开源的CORBA通讯框架,在C的示例中,使用了orbit的框架。
如我用的是Debian系统,可以直接安装:
apt-get install orbit2 apt-get install orbit2-nameserver apt-get install liborbit2-dev |
安装后,可以通过工具orb-rdl-2从idl文件生成需要的stubs及skeletons接口代码:
#该命令会生成文件:Hi.h、Hi-common.c、Hi-skels.c、Hi-stubs.c orbit-idl-2 Hi.idl |
可以通过工具orb-rdl-2从idl文件生成服务端代码:
#该命令会生成模板文件:Hi-skelimpl.c orbit-idl-2 --skeleton-impl Hi.idl |
首先完成服务端部分:
Hi-server-ns.c
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <signal.h> #include <orbit/orbit.h> #include <ORBitservices/CosNaming.h> #include <ORBitservices/CosNaming_impl.h> #include "Hi.h" #include "Hi-skelimpl.c" /* ./Hi-server_ns */ /** * test for exception */ static gboolean raised_exception(CORBA_Environment *ev) { return ((ev)->_major != CORBA_NO_EXCEPTION); } /** * in case of any exception this macro will abort the process */ static void abort_if_exception(CORBA_Environment *ev, const char * mesg) { if (raised_exception (ev)) { g_error ( "%s %s" , mesg, CORBA_exception_id (ev)); CORBA_exception_free (ev); abort (); } } /* * main */ int main ( int argc, char *argv[]) { PortableServer_POA poa; HiCorba_Hi servant = CORBA_OBJECT_NIL; CosNaming_NamingContext ns =CORBA_OBJECT_NIL; CORBA_ORB orb=CORBA_OBJECT_NIL; CORBA_char name_service[]= "Hi" ; CosNaming_NameComponent path[1]={name_service, "" }; CosNaming_Name name={1,1,path,CORBA_FALSE}; CORBA_Environment ev; // init ORB g_print( "\nServer>starting server..." ); g_print( "\nServer>creating and initializing the ORB" ); CORBA_exception_init(&ev); abort_if_exception(&ev, "CORBA_exception_init failed" ); orb=CORBA_ORB_init(&argc,argv, "orbit-local-orb" ,&ev); abort_if_exception(&ev, "CORBA_ORB_init failed" ); // activate POA g_print( "\nServer>getting reference to RootPOA" ); poa= (PortableServer_POA) CORBA_ORB_resolve_initial_references(orb, "RootPOA" ,&ev); abort_if_exception(&ev, "CORBA_ORB_resolve_initial 'RootPOA' failed" ); g_print( "\nServer>activating the POA Manager" ); PortableServer_POAManager_activate(PortableServer_POA__get_the_POAManager(poa, &ev),&ev); abort_if_exception(&ev, "POA_activate failed" ); // create servant g_print( "\nServer>creating the servant" ); servant = impl_HiCorba_Hi__create (poa, &ev); abort_if_exception(&ev, "impl_HiCorba_Hi__create failed" ); // read name_service ior from ns.ior CORBA_char filename[] = "ns.ior" ; FILE *file = NULL; g_print( "\nServer>reading the file '%s'" ,filename); if ((file= fopen (filename, "r" ))==NULL) g_error ( "could not open '%s'\n" , filename); gchar objref[1024]; fscanf (file, "%s" , &objref); g_print( "\nServer>getting the root naming context 'NameService' - from the file '%s'" ,filename); g_print( "\nServer>the root naming context ior is '%s'" ,objref); // bind service ns = (CosNaming_NamingContext) CORBA_ORB_string_to_object (orb, objref, &ev); //free (objref); abort_if_exception(&ev, "CORBA_ORB_string_to_object 'NameService IOR' failed" ); g_print( "\nServer>binding the object reference in naming with name '%s'" ,name_service); CosNaming_NamingContext_rebind(ns,&name,servant,&ev); abort_if_exception(&ev, "rebind failed" ); // start g_print( "\nServer>running the orb..." ); CORBA_ORB_run(orb,&ev); abort_if_exception(&ev, "ORB_run failed" ); } |
Hi-skelimpl.c
/* This is a template file generated by command */ /* orbit-idl-2 --skeleton-impl Hi.idl */ /* User must edit this file, inserting servant */ /* specific code between markers. */ #include <stdlib.h> #include <stdio.h> #include "Hi.h" /*** App-specific servant structures ***/ #if !defined(_typedef_impl_POA_HiCorba_Hi_) #define _typedef_impl_POA_HiCorba_Hi_ 1 typedef struct { POA_HiCorba_Hi servant; PortableServer_POA poa; /* ------ add private attributes here ------ */ /* ------ ---------- end ------------ ------ */ } impl_POA_HiCorba_Hi; #endif /*** Implementation stub prototypes ***/ #if !defined(_decl_impl_HiCorba_Hi__destroy_) #define _decl_impl_HiCorba_Hi__destroy_ 1 static void impl_HiCorba_Hi__destroy(impl_POA_HiCorba_Hi *servant, CORBA_Environment *ev); #endif #if !defined(_decl_impl_HiCorba_Hi_sayHiTo_) #define _decl_impl_HiCorba_Hi_sayHiTo_ 1 static CORBA_string impl_HiCorba_Hi_sayHiTo(impl_POA_HiCorba_Hi *servant, const CORBA_char * someone, CORBA_Environment *ev); #endif #if !defined(_decl_impl_HiCorba_Hi_add_) #define _decl_impl_HiCorba_Hi_add_ 1 static CORBA_long impl_HiCorba_Hi_add(impl_POA_HiCorba_Hi *servant, const CORBA_long numa, const CORBA_long numb, CORBA_Environment *ev); #endif #if !defined(_decl_impl_HiCorba_Hi_shutdown_) #define _decl_impl_HiCorba_Hi_shutdown_ 1 static void impl_HiCorba_Hi_shutdown(impl_POA_HiCorba_Hi *servant, CORBA_Environment *ev); #endif /*** epv structures ***/ #if !defined(_impl_HiCorba_Hi_base_epv_) #define _impl_HiCorba_Hi_base_epv_ 1 static PortableServer_ServantBase__epv impl_HiCorba_Hi_base_epv = { NULL, /* _private data */ (gpointer) & impl_HiCorba_Hi__destroy, /* finalize routine */ NULL, /* default_POA routine */ }; #endif #if !defined(_impl_HiCorba_Hi_epv_) #define _impl_HiCorba_Hi_epv_ 1 static POA_HiCorba_Hi__epv impl_HiCorba_Hi_epv = { NULL, /* _private */ (gpointer)&impl_HiCorba_Hi_sayHiTo, (gpointer)&impl_HiCorba_Hi_add, (gpointer)&impl_HiCorba_Hi_shutdown, }; #endif /*** vepv structures ***/ #if !defined(_impl_HiCorba_Hi_vepv_) #define _impl_HiCorba_Hi_vepv_ 1 static POA_HiCorba_Hi__vepv impl_HiCorba_Hi_vepv = { &impl_HiCorba_Hi_base_epv, &impl_HiCorba_Hi_epv, }; #endif /*** Stub implementations ***/ #if !defined(_impl_HiCorba_Hi__create_) #define _impl_HiCorba_Hi__create_ 1 static HiCorba_Hi impl_HiCorba_Hi__create(PortableServer_POA poa, CORBA_Environment *ev) { HiCorba_Hi retval; impl_POA_HiCorba_Hi *newservant; PortableServer_ObjectId *objid; newservant = g_new0(impl_POA_HiCorba_Hi, 1); newservant->servant.vepv = &impl_HiCorba_Hi_vepv; newservant->poa = (PortableServer_POA) CORBA_Object_duplicate((CORBA_Object)poa, ev); POA_HiCorba_Hi__init((PortableServer_Servant)newservant, ev); /* Before servant is going to be activated all * private attributes must be initialized. */ /* ------ init private attributes here ------ */ /* ------ ---------- end ------------- ------ */ objid = PortableServer_POA_activate_object(poa, newservant, ev); CORBA_free(objid); retval = PortableServer_POA_servant_to_reference(poa, newservant, ev); return retval; } #endif #if !defined(_impl_HiCorba_Hi__destroy_) #define _impl_HiCorba_Hi__destroy_ 1 static void impl_HiCorba_Hi__destroy(impl_POA_HiCorba_Hi *servant, CORBA_Environment *ev) { CORBA_Object_release ((CORBA_Object) servant->poa, ev); /* No further remote method calls are delegated to * servant and you may free your private attributes. */ /* ------ free private attributes here ------ */ /* ------ ---------- end ------------- ------ */ POA_HiCorba_Hi__fini((PortableServer_Servant)servant, ev); g_free (servant); } #endif #if !defined(_impl_HiCorba_Hi_sayHiTo_) #define _impl_HiCorba_Hi_sayHiTo_ 1 static CORBA_string impl_HiCorba_Hi_sayHiTo(impl_POA_HiCorba_Hi *servant, const CORBA_char * someone, CORBA_Environment *ev) { CORBA_string retval = CORBA_string_alloc(512); /* ------ insert method code here ------ */ sprintf (retval, "Hi, %s !" ,someone); g_print( "\nServer>server is returning: %s" ,retval); /* ------ ---------- end ------------ ------ */ return retval; } #endif #if !defined(_impl_HiCorba_Hi_add_) #define _impl_HiCorba_Hi_add_ 1 static CORBA_long impl_HiCorba_Hi_add(impl_POA_HiCorba_Hi *servant, const CORBA_long numa, const CORBA_long numb, CORBA_Environment *ev) { CORBA_long retval; /* ------ insert method code here ------ */ retval = numa+numb; /* ------ ---------- end ------------ ------ */ return retval; } #endif #if !defined(_impl_HiCorba_Hi_shutdown_) #define _impl_HiCorba_Hi_shutdown_ 1 static CORBA_ORB _neo_ORB = CORBA_OBJECT_NIL; static HiCorba_Hi _neo_servant = CORBA_OBJECT_NIL; static void set_NEO_ORB(CORBA_ORB theORB, HiCorba_Hi theServant) { _neo_ORB = theORB; _neo_servant = theServant; } static void impl_HiCorba_Hi_shutdown(impl_POA_HiCorba_Hi *servant, CORBA_Environment *ev) { /* ------ insert method code here ------ */ if (_neo_ORB==CORBA_OBJECT_NIL || _neo_servant == CORBA_OBJECT_NIL) return ; // g_print( "\nServer>executing the release" ); CORBA_Object_release(_neo_servant,ev); if ((ev)->_major != CORBA_NO_EXCEPTION){ g_error ( "%s %s" , "Object_release failed" , CORBA_exception_id (ev)); CORBA_exception_free (ev); abort (); } // g_print( "\nServer>executing the shutdown" ); CORBA_ORB_shutdown(_neo_ORB, CORBA_FALSE, ev); if ((ev)->_major != CORBA_NO_EXCEPTION){ g_error ( "%s %s" , "shutdown failed" , CORBA_exception_id (ev)); CORBA_exception_free (ev); abort (); } exit (0); /* ------ ---------- end ------------ ------ */ } #endif |
MakeServer
CC = gcc CFLAGS = -c -g -pthread -D_REENTRANT -DORBIT2=1 \ -I /usr/include/orbit-2 .0 \ -I /usr/include/glib-2 .0 \ -I /usr/lib/x86_64-linux-gnu/glib-2 .0 /include LDFLAGS = -Wl,-- export -dynamic -lORBit-2 -lORBitCosNaming-2 -lgmodule-2.0 \ -ldl -lgobject-2.0 -lgthread-2.0 -lpthread -lglib-2.0 -lm \ -L /usr/lib ORBIT_IDL= /usr/bin/orbit-idl-2 all : Hi-server-ns.bin Hi-server-ns.bin : Hi-common.o Hi-skelimpl.o Hi-skels.o Hi-server-ns.o $(CC) $(LDFLAGS) Hi-common.o Hi-skelimpl.o Hi-skels.o Hi-server-ns.o -o Hi-server-ns.bin %.o : %.c $(CC) $(CFLAGS) $< -o $@ nidl : Hi.idl $(ORBIT_IDL) Hi.idl $(ORBIT_IDL) --skeleton-impl Hi.idl clean: rm -rf *.bin rm -rf *.o |
编译
make -f MakeServer |
DBUS发送接收数据(下)
1、编译后,由于没有进行配置,默认是无法运行的。
为了可以正常运行,增加或修改下面的配置文件即可。
/etc/dbus-1.0/system-local.conf
<!-- This configuration file controls the systemwide message bus. Add a system-local.conf and edit that rather than changing this file directly. --> <!-- Note that there are any number of ways you can hose yourself security-wise by screwing up this file; in particular, you probably don't want to listen on any more addresses, add any more auth mechanisms, run as a different user, etc. --> <! DOCTYPE busconfig PUBLIC "-//freedesktop//DTD D-Bus Bus Configuration 1.0//EN" "http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd"> < busconfig > <!-- Our well-known bus type, do not change this --> < type >system</ type > <!-- Run as special user --> < user >messagebus</ user > <!-- Fork into daemon mode --> < fork /> <!-- We use system service launching using a helper --> < standard_system_servicedirs /> <!-- This is a setuid helper that is used to launch system services --> < servicehelper >/usr/lib/dbus-1.0/dbus-daemon-launch-helper</ servicehelper > <!-- Write a pid file --> < pidfile >/var/run/dbus/pid</ pidfile > <!-- Enable logging to syslog --> < syslog /> <!-- Only allow socket-credentials-based authentication --> < auth >EXTERNAL</ auth > <!-- Only listen on a local socket. (abstract=/path/to/socket means use abstract namespace, don't really create filesystem file; only Linux supports this. Use path=/whatever on other systems.) --> < listen >unix:path=/var/run/dbus/system_bus_socket</ listen > < policy context = "default" > <!-- All users can connect to system bus --> < allow user = "*" /> <!-- Holes must be punched in service configuration files for name ownership and sending method calls --> < allow own = "*" /> < allow send_type = "method_call" /> <!-- Signals and reply messages (method returns, errors) are allowed by default --> < allow send_type = "signal" /> < allow send_requested_reply = "true" send_type = "method_return" /> < allow send_requested_reply = "true" send_type = "error" /> <!-- All messages may be received by default --> < allow receive_type = "method_call" /> < allow receive_type = "method_return" /> < allow receive_type = "error" /> < allow receive_type = "signal" /> <!-- Allow anyone to talk to the message bus --> < allow send_destination = "org.freedesktop.DBus" /> <!-- But disallow some specific bus services --> < deny send_destination = "org.freedesktop.DBus" send_interface = "org.freedesktop.DBus" send_member = "UpdateActivationEnvironment" /> < deny send_destination = "org.freedesktop.DBus" send_interface = "org.freedesktop.systemd1.Activator" /> </ policy > <!-- Only systemd, which runs as root, may report activation failures. --> < policy user = "root" > < allow send_destination = "org.freedesktop.DBus" send_interface = "org.freedesktop.systemd1.Activator" /> </ policy > <!-- Config files are placed here that among other things, punch holes in the above policy for specific services. --> < includedir >system.d</ includedir > < include if_selinux_enabled = "yes" selinux_root_relative = "yes" >contexts/dbus_contexts</ include > </ busconfig > |
2、测试消息发送
服务端:
$. /testdbus_s .bin receive Listening for signals Match rule sent Got Signal with value: Hello Got Signal with value: Hi Bye...... |
客户端:
$. /testdbus_s .bin send Hello Sending signal with value: Hello Signal Sent $. /testdbus_s .bin send Hi Sending signal with value: Hi Signal Sent $. /testdbus_s .bin send Bye Sending signal with value: Bye Signal Sent |
3、测试方法调用
服务端:
$. /testdbus_s .bin listen Listening for method calls Method Invoked with value: Hello Method Invoked with value: Hi Bye...... |
客户端:
$. /testdbus_s .bin query Hello Calling remote method with Hello Request Sent Got Reply: 1, 21614 $. /testdbus_s .bin query Hi Calling remote method with Hi Request Sent Got Reply: 1, 21614 $. /testdbus_s .bin query Bye Calling remote method with Bye Request Sent Got Reply: 1, 21614 |
DBUS发送接收数据(上)
1、Server端
testdbus_s.c
#define DBUS_API_SUBJECT_TO_CHANGE #include <dbus/dbus.h> #include <stdbool.h> #include <unistd.h> #include <stdio.h> #include <stdlib.h> /** * Wait for signals on the bus and reply */ void receive() { DBusMessage* msg; DBusMessageIter args; DBusConnection* conn; DBusError err; int ret; char * sigvalue; int loop=1; printf ( "Listening for signals\n" ); // initialise the errors dbus_error_init(&err); // connect to the bus and check for errors conn = dbus_bus_get(DBUS_BUS_SYSTEM, &err); if (dbus_error_is_set(&err)) { fprintf (stderr, "Connection Error (%s)\n" , err.message); dbus_error_free(&err); } if (NULL == conn) { exit (1); } // request our name on the bus and check for errors ret = dbus_bus_request_name(conn, "neohope.dbus.signal.target" , DBUS_NAME_FLAG_REPLACE_EXISTING , &err); if (dbus_error_is_set(&err)) { fprintf (stderr, "Name Error (%s)\n" , err.message); dbus_error_free(&err); } if (DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER != ret) { exit (1); } // add a rule for which messages we want to see dbus_bus_add_match(conn, "type='signal',interface='neohope.dbus.signal.Type'" , &err); // see signals from the given interface dbus_connection_flush(conn); if (dbus_error_is_set(&err)) { fprintf (stderr, "Match Error (%s)\n" , err.message); exit (1); } printf ( "Match rule sent\n" ); // loop listening for signals being emmitted while (loop) { // non blocking read of the next available message dbus_connection_read_write(conn, 0); msg = dbus_connection_pop_message(conn); // loop again if we haven't read a message if (NULL == msg) { sleep(1); continue ; } // check if the message is a signal from the correct interface and with the correct name if (dbus_message_is_signal(msg, "neohope.dbus.signal.Type" , "TestSignal" )) { // read the parameters if (!dbus_message_iter_init(msg, &args)) fprintf (stderr, "Message Has No Parameters\n" ); else if (DBUS_TYPE_STRING != dbus_message_iter_get_arg_type(&args)) fprintf (stderr, "Argument is not string!\n" ); else dbus_message_iter_get_basic(&args, &sigvalue); if ( strcmp ( "Bye" ,sigvalue)==0) { loop = 0; printf ( "Bye......\n" ); } else { printf ( "Got Signal with value: %s\n" , sigvalue); } } // free the message dbus_message_unref(msg); } // do not close the connection // dbus_connection_close(conn); } /** * Deal with remote method call */ int reply_to_method_call(DBusMessage* msg, DBusConnection* conn) { DBusMessage* reply; DBusMessageIter args; int stat = 1; int ret = 1; dbus_uint32_t level = 21614; dbus_uint32_t serial = 0; char * param = "" ; // read the arguments if (!dbus_message_iter_init(msg, &args)) fprintf (stderr, "Message has no arguments!\n" ); else if (DBUS_TYPE_STRING != dbus_message_iter_get_arg_type(&args)) fprintf (stderr, "Argument is not string!\n" ); else dbus_message_iter_get_basic(&args, ¶m); if ( strcmp ( "Bye" ,param)==0){ ret = 0; printf ( "Bye......\n" ); } else { printf ( "Method Invoked with value: %s\n" , sigvalue); } // create a reply from the message reply = dbus_message_new_method_return(msg); // add the arguments to the reply dbus_message_iter_init_append(reply, &args); if (!dbus_message_iter_append_basic(&args, DBUS_TYPE_BOOLEAN, &stat)) { fprintf (stderr, "Out Of Memory!\n" ); exit (1); } if (!dbus_message_iter_append_basic(&args, DBUS_TYPE_UINT32, &level)) { fprintf (stderr, "Out Of Memory!\n" ); exit (1); } // send the reply && flush the connection if (!dbus_connection_send(conn, reply, &serial)) { fprintf (stderr, "Out Of Memory!\n" ); exit (1); } dbus_connection_flush(conn); // free the reply dbus_message_unref(reply); return ret; } /** * Server that exposes a method call and waits for it to be called */ void listen() { DBusMessage* msg; DBusMessage* reply; DBusMessageIter args; DBusConnection* conn; DBusError err; int loop = 1; int ret; char * param; printf ( "Listening for method calls\n" ); // initialise the error dbus_error_init(&err); // connect to the bus and check for errors conn = dbus_bus_get(DBUS_BUS_SYSTEM, &err); if (dbus_error_is_set(&err)) { fprintf (stderr, "Connection Error (%s)\n" , err.message); dbus_error_free(&err); } if (NULL == conn) { fprintf (stderr, "Connection Null\n" ); exit (1); } // request our name on the bus and check for errors ret = dbus_bus_request_name(conn, "neohope.dbus.method.provider" , DBUS_NAME_FLAG_REPLACE_EXISTING , &err); if (dbus_error_is_set(&err)) { fprintf (stderr, "Name Error (%s)\n" , err.message); dbus_error_free(&err); } if (DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER != ret) { fprintf (stderr, "Not Primary Owner (%d)\n" , ret); exit (1); } // loop, testing for new messages while (loop) { // non blocking read of the next available message dbus_connection_read_write(conn, 0); msg = dbus_connection_pop_message(conn); // loop again if we haven't got a message if (NULL == msg) { sleep(1); continue ; } // check this is a method call for the right interface & method if (dbus_message_is_method_call(msg, "neohope.dbus.method.Type" , "TestMethod" )) loop = reply_to_method_call(msg, conn); // free the message dbus_message_unref(msg); } // do not close the connection // dbus_connection_close(conn); } int main( int argc, char ** argv) { if (2 > argc) { printf ( "Syntax: testdbus_s [receive|listen] [<param>]\n" ); return 1; } char * param = "no param" ; if (3 >= argc && NULL != argv[2]) param = argv[2]; if (0 == strcmp (argv[1], "receive" )) receive(); else if (0 == strcmp (argv[1], "listen" )) listen(); else { printf ( "Syntax: testdbus_s [receive|listen] [<param>]\n" ); return 1; } return 0; } |
2、Client端
testdbus_c.c
#define DBUS_API_SUBJECT_TO_CHANGE #include <dbus/dbus.h> #include <stdbool.h> #include <unistd.h> #include <stdio.h> #include <stdlib.h> /** * Connect to the DBUS bus and send a broadcast signal */ void sendsignal( char * sigvalue) { DBusMessage* msg; DBusMessageIter args; DBusConnection* conn; DBusError err; int ret; dbus_uint32_t serial = 0; printf ( "Sending signal with value: %s\n" , sigvalue); // initialise the error value dbus_error_init(&err); // connect to the DBUS system bus, and check for errors conn = dbus_bus_get(DBUS_BUS_SYSTEM, &err); if (dbus_error_is_set(&err)) { fprintf (stderr, "Connection Error (%s)\n" , err.message); dbus_error_free(&err); } if (NULL == conn) { exit (1); } // register our name on the bus, and check for errors ret = dbus_bus_request_name(conn, "neohope.dbus.signal.source" , DBUS_NAME_FLAG_REPLACE_EXISTING , &err); if (dbus_error_is_set(&err)) { fprintf (stderr, "Name Error (%s)\n" , err.message); dbus_error_free(&err); } if (DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER != ret) { exit (1); } // create a signal & check for errors msg = dbus_message_new_signal( "/neohope/dbus/signal/Object" , // object name of the signal "neohope.dbus.signal.Type" , // interface name of the signal "TestSignal" ); // name of the signal if (NULL == msg) { fprintf (stderr, "Message Null\n" ); exit (1); } // append arguments onto signal dbus_message_iter_init_append(msg, &args); if (!dbus_message_iter_append_basic(&args, DBUS_TYPE_STRING, &sigvalue)) { fprintf (stderr, "Out Of Memory!\n" ); exit (1); } // send the message and flush the connection if (!dbus_connection_send(conn, msg, &serial)) { fprintf (stderr, "Out Of Memory!\n" ); exit (1); } dbus_connection_flush(conn); printf ( "Signal Sent\n" ); // free the message dbus_message_unref(msg); // do not close the connection // dbus_connection_close(conn); } /** * Call a method on a remote object */ void query( char * param) { DBusMessage* msg; DBusMessageIter args; DBusConnection* conn; DBusError err; DBusPendingCall* pending; int ret; int stat; dbus_uint32_t level; printf ( "Calling remote method with %s\n" , param); // initialiset the errors dbus_error_init(&err); // connect to the system bus and check for errors conn = dbus_bus_get(DBUS_BUS_SYSTEM, &err); if (dbus_error_is_set(&err)) { fprintf (stderr, "Connection Error (%s)\n" , err.message); dbus_error_free(&err); } if (NULL == conn) { exit (1); } // request our name on the bus ret = dbus_bus_request_name(conn, "neohope.dbus.method.caller" , DBUS_NAME_FLAG_REPLACE_EXISTING , &err); if (dbus_error_is_set(&err)) { fprintf (stderr, "Name Error (%s)\n" , err.message); dbus_error_free(&err); } if (DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER != ret) { exit (1); } // create a new method call and check for errors msg = dbus_message_new_method_call( "neohope.dbus.method.provider" , // target for the method call "/neohope/dbus/method/Object" , // object to call on "neohope.dbus.method.Type" , // interface to call on "TestMethod" ); // method name if (NULL == msg) { fprintf (stderr, "Message Null\n" ); exit (1); } // append arguments dbus_message_iter_init_append(msg, &args); if (!dbus_message_iter_append_basic(&args, DBUS_TYPE_STRING, ¶m)) { fprintf (stderr, "Out Of Memory!\n" ); exit (1); } // send message and get a handle for a reply if (!dbus_connection_send_with_reply (conn, msg, &pending, -1)) { // -1 is default timeout fprintf (stderr, "Out Of Memory!\n" ); exit (1); } if (NULL == pending) { fprintf (stderr, "Pending Call Null\n" ); exit (1); } dbus_connection_flush(conn); printf ( "Request Sent\n" ); // free message dbus_message_unref(msg); // block until we recieve a reply dbus_pending_call_block(pending); // get the reply message msg = dbus_pending_call_steal_reply(pending); if (NULL == msg) { fprintf (stderr, "Reply Null\n" ); exit (1); } // free the pending message handle dbus_pending_call_unref(pending); // read the parameters if (!dbus_message_iter_init(msg, &args)) fprintf (stderr, "Message has no arguments!\n" ); else if (DBUS_TYPE_BOOLEAN != dbus_message_iter_get_arg_type(&args)) fprintf (stderr, "Argument is not boolean!\n" ); else dbus_message_iter_get_basic(&args, &stat); if (!dbus_message_iter_next(&args)) fprintf (stderr, "Message has too few arguments!\n" ); else if (DBUS_TYPE_UINT32 != dbus_message_iter_get_arg_type(&args)) fprintf (stderr, "Argument is not int!\n" ); else dbus_message_iter_get_basic(&args, &level); printf ( "Got Reply: %d, %d\n" , stat, level); // free reply and close connection dbus_message_unref(msg); //dbus_connection_close(conn); } int main( int argc, char ** argv) { if (2 > argc) { printf ( "Syntax: testdbus_c [send|query] [<param>]\n" ); return 1; } char * param = "no param" ; if (3 >= argc && NULL != argv[2]) param = argv[2]; if (0 == strcmp (argv[1], "send" )) sendsignal(param); else if (0 == strcmp (argv[1], "query" )) query(param); else { printf ( "Syntax: testdbus_c [send|query] [<param>]\n" ); return 1; } return 0; } |
3、Makefile
CC=gcc LDFLAGS+=-ldbus-1 CFLAGS+=-I/usr/include/dbus-1.0 -I/usr/lib/x86_64-linux-gnu/dbus-1.0/include/ all:testdbus_c.bin testdbus_s.bin testdbus_c.bin:testdbus_c.o $(CC) $(LDFLAGS) -o testdbus_c.bin testdbus_c.o testdbus_c.o:testdbus_c.c $(CC) $(CFLAGS) -c -o testdbus_c.o testdbus_c.c testdbus_s.bin:testdbus_s.o $(CC) $(LDFLAGS) -o testdbus_s.bin testdbus_s.o testdbus_s.o:testdbus_s.c $(CC) $(CFLAGS) -c -o testdbus_s.o testdbus_s.c clean: rm *.o *.bin |
4、编译
make |
排序算法C Part01
1、冒泡排序
//冒泡排序BubbleSort //每次扫描,比较和交换相邻元素,保证一次扫描后,最大元素在最后一个 //每次扫描后,扫描队列长度减一 //时间复杂度:O(N^2) //空间复杂度:O(N) //稳定性:稳定 //输入:要排序的数组,数组长度 //输出:void,Q[]将处于排序状态 void BubbleSort( int Q[], int N) { int i; int swap=1; int Temp; while (swap>0) { swap=0; for (i=1;i<N;i++) { if (Q[i-1]>Q[i]) { swap++; Temp=Q[i-1]; Q[i-1]=Q[i]; Q[i]=Temp; } } } } |
2、选择排序
//选择排序SelectionSort //从头扫描到尾,每次将最小元素放到第一个 //每次扫描后,队列长度减一 //时间复杂度:O(N^2) //空间复杂度:O(N) //稳定性:稳定 //输入:要排序的数组,数组长度 //输出:void,Q[]将处于排序状态 void SelectionSort( int Q[], int N) { int i,j,k; int Temp; for (i=0;i<N;i++) { k=i; for (j=i+1;j<N;j++) { if (Q[j]<Q[i])k=j; } Temp=Q[k]; Q[k]=Q[i]; Q[i]=Temp; } } |
3、插入排序
//插入排序InsertionSort //起始队列长度为1,每次队列长度加1 //通过元素移动,将队列调整为有序状态 //时间复杂度:O(N^2) //空间复杂度:O(N) //稳定性:稳定 //输入:要排序的数组,数组长度 //输出:void,Q[]将处于排序状态 void InsertionSort( int Q[], int N) { int i,j; int Temp; for (i=1;i<N;i++) { Temp = Q[i]; for (j=i;j>0 && Q[j-1]>Temp;j--) { Q[j]=Q[j-1]; } Q[j]=Temp; } } |
4、希尔排序
//希尔排序ShellSort //指定一个步长,将需要排序的数字,按序号%步长分组 //对每组进行插入排序,然后减小步长,再次分组,排序直到步长为1结束 //时间复杂度:O(n^2) //空间复杂度:O(n) //稳定性:稳定 //输入:要排序的数组,数组长度 //输出:void,Q[]将处于排序状态 void ShellSort( int Q[], int N) { int i,j; int Temp; int Step; for (Step=N/2;Step>0;Step=Step/2) { for (i=Step;i<N;i++) { Temp = Q[i]; for (j=i;j>=Step && Q[j-Step]>Temp;j=j-Step) { Q[j]=Q[j-Step]; } Q[j]=Temp; } //dumpArray(Q,N); } } |
5、归并排序
//归并排序MergeSort //二路归并首先将归并长度定为2,在归并集内进行排序 //然后归并长度×2,将有序集合进行归并 //时间复杂度:O(NlogN) //空间复杂度:O(N) //稳定性:稳定 //输入:要排序的数组,数组长度 //输出:void,Q[]将处于排序状态 void Merge( int Q[], int TempArray[], int left, int mid, int right) { int i=left,j=mid,k=left; while (i<mid && j<=right) { if (Q[i]>Q[j]) { TempArray[k++]=Q[j++]; } else { TempArray[k++]=Q[i++]; } } while (i<mid) { TempArray[k++]=Q[i++]; } while (j<=right) { TempArray[k++]=Q[j++]; } for (k=left;k<=right;k++) { Q[k]=TempArray[k]; } } void MSort( int Q[], int TempArray[], int left, int right) { int center; if (left<right) { center=(left+right)/2; MSort(Q,TempArray,left,center); MSort(Q,TempArray,center+1,right); Merge(Q,TempArray,left,center+1,right); } } void MergeSort( int Q[], int N) { int *TempArray = malloc (N* sizeof ( int )); if (TempArray!=NULL) { MSort(Q,TempArray,0,N-1); } else { //Todo: deal with not enough memory //RaiseError("MergeSort: not enough memory"); } } |