C++ 0x keynote(以下简称0x)中描述了这样一个看起来不错的东西:
1、本地调用代码:
// use local object:
X x;
A a;
std::string s("abc");
// …
x.f(a, s);
2、使用远程代理wrapper层:
// use remote object :
proxy<X> x;
x.connect("my_host");
A a;
std::string s("abc");
// …
x.f(a, s);
仅使用一个包装层就完成远程调用?从目前的C++来看基本上不可能。 今天突然想到可以使用aspect c++来生成代码,因为aspect c++在生成代码时,也生成了一些简单的元信息,可以在函数里面取得函数的原型、各参数的类型等。 根据0x的描述,我编写了简单的测试代码:
#include <string>
#include <iostream>
#include <sstream>
#include <vector>
using namespace std;
class LoginService
{
public:
virtual bool login (const string& name, const string& password, string& session) = 0;
virtual void logout (const string& session) = 0;
};
class RemoteCall
{
public:
bool connect (const char* host, unsigned short port)
{
cout << "connect success" << endl;
return true;
}
bool send (const char* p, size_t len)
{
cout << "send: " << endl;
cout << string(p, len) << endl;
return true;
}
bool recv(char* p, size_t len)
{
return true;
}
};
class RemoteLoginService : public LoginService, public RemoteCall
{
public:
virtual bool login (const string& name, const string& password, string& session)
{
return false;
}
virtual void logout (const string& session)
{
}
};
int main(int argc, char *argv[])
{
RemoteLoginService rls;
rls.connect("localhost", 3957);
string session;
rls.login("lijie", "lijie", session);
rls.logout(session);
return 0;
}
现在的目标是加入一个方面,让RemoteLoginService具有远程调用功能。当然由于此处RemoteCall并未实现,所以只要能够把这个调用正确序列化就算完成目标。 这个方面完成后如下:
aspect Remote
{
pointcut remote_class() = "RemoteCall";
pointcut remote_call() = derived(remote_class()) && !remote_class();
pointcut virtual_methods() = "% ...::%(...)";
advice within(remote_call()) && execution(virtual_methods()): before(){
stringstream ss;
ss << "\tcall:" << JoinPoint::signature() << endl;
ss << "\targuments:";
for (size_t i=0; i<JoinPoint::args(); ++i)
{
string arg(tjp->argtype(i));
if (arg.find("basic_string") != arg.npos)
{
ss << *(string*)tjp->arg(i) << "|";
}
}
string send_str = ss.str();
tjp->target()->send (send_str.c_str(), send_str.size());
}
advice within(remote_call()) && execution(virtual_methods()): after(){
vector<char> buffer(1024, '\0');
tjp->target()->recv (&(*buffer.begin()), buffer.size());
// 解析接收的数据,远程调用结果写入tjp->result()指向的内存
}
};
它匹配所有从RemoteCall上派生的类,为它的每个方法加入远程调用代码以及调用结果处理代码。 生成并编译运行,输出如下:
connect success
send:
call:bool RemoteLoginService::login(const ::std::basic_string< char > &,const ::std::basic_string< char > &,::std::basic_string< char > &)
arguments:lijie|lijie||
send:
call:void RemoteLoginService::logout(const ::std::basic_string< char > &)
arguments:|
由于完整序列化了各个参数值,第一个目标——生成远程调用代码——算是完成了。
下一个目标,考虑服务端如何编写?服务端需要开启一个服务,并注册各个服务接口。
要达到这个目标,aspect c++需要提供类、方法级别的类型及名称获取,不过aspect c++在这方面没有提供更多方便,现在只能在方法执行时获得方法的信息,它所生成的“元信息”过于简单,而且为了效率考虑都实现为各个独立的结构,结构的成员也大都是static的,所以无法使用一个合适的接口来反射,期待以后能加入这些特性。
所以这第2个目标实际上无法简单地完成,除非在服务端手工添加服务注册代码,这个部分工作量稍小,但还是可以做到的。
相关推荐
C++平台的面向切面编程(aop)的理论知识。需要的直接拿去研究吧。
整理的Spring AOP Aspect切入点语法,老师整理的,2018.08.01最新版
NULL 博文链接:https://chenhongwei0924.iteye.com/blog/845772
AOP 和 Aspect 注解切入 测试 Demo 1.ProxyFactory 基于 MethodBeforeAdvice、AfterReturningAdvice 利用 Spring Api 定义前、后置处理方法,并通过代理工厂类获取代理对象(代码或Xml配置实现) 2.ProxyFactoryBean...
spirng远程调用可运行简单实例。包含所需所有jar spring-*-3.*.RELEASE.jar aopalliance.jar等。
springaop详细解释以及代码实现demo,包含了所以aop通知类型
详细介绍了AOP的核心功能(拦截功能)在底层是如何实现的;介绍了两种实现AOP的动态代理:jdk动态代理和cglib动态代理,并详细描述了它们在代码层面的实现。附有必须的cglib.jar和asm.jar
本文档记录了在c++语言中使用AOP的技术
Spring源代码解析(七):Spring_AOP中对拦截器调用的实现.doc
aop权限代码,真实项目代码,spring2.5
深入理解Android之AOP;深入理解Android之AOP;深入理解Android之AOP
Spring AOP测试代码
基于spring4实现的AOP源代码。此源代码解压即用。
Spring的AOP开发(XML)Spring的AOP的注解开发 代码案例
java开发过程中需要用到aspect,这时候需要用到相应的jar包。
主要介绍了基于spring@aspect注解的aop实现过程代码实例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
Spring AOP 常用于日志记录,性能统计,安全控制,事务处理,异常处理等等,本项目对其常用语法进行示例。
3、可大大提高开发效率,数据表创建完以后,自动生成entity,mapper.xml,dao,service,controller,vo,dto相关代码。 4、本项目集成了spring,aop,mybatis plus,swagger2,异常处理,分页,freemarker等多种技术。 5、操作...
AOP(Aspect-Oriented Programming)这个东西,名字与 OOP 仅差一个字母,其实它是对 OOP 编程方式的一种补充,并非是取而代之。翻译过来就是“面向方面编程”,可我更倾向于翻译为“面向切面编程”。最好的演示案例...