??xml version="1.0" encoding="utf-8" standalone="yes"?>MM131亚洲国产美女久久,青青草原综合久久大伊人,新狼窝色AV性久久久久久http://www.shnenglu.com/cpunion/category/48.htmlAS/C/C++/D/Java/JS/Python/Rubyzh-cnMon, 26 May 2008 15:24:30 GMTMon, 26 May 2008 15:24:30 GMT60搬家http://www.shnenglu.com/cpunion/archive/2006/10/09/13499.htmlqieziqieziMon, 09 Oct 2006 14:33:00 GMThttp://www.shnenglu.com/cpunion/archive/2006/10/09/13499.htmlhttp://www.shnenglu.com/cpunion/comments/13499.htmlhttp://www.shnenglu.com/cpunion/archive/2006/10/09/13499.html#Feedback0http://www.shnenglu.com/cpunion/comments/commentRss/13499.htmlhttp://www.shnenglu.com/cpunion/services/trackbacks/13499.html

qiezi 2006-10-09 22:33 发表评论
]]>
D落文本渲染引擎http://www.shnenglu.com/cpunion/archive/2006/10/09/13484.htmlqieziqieziMon, 09 Oct 2006 03:44:00 GMThttp://www.shnenglu.com/cpunion/archive/2006/10/09/13484.htmlhttp://www.shnenglu.com/cpunion/comments/13484.htmlhttp://www.shnenglu.com/cpunion/archive/2006/10/09/13484.html#Feedback0http://www.shnenglu.com/cpunion/comments/commentRss/13484.htmlhttp://www.shnenglu.com/cpunion/services/trackbacks/13484.html
有了(jin)freetype实现底层字体渲染Q我只需要处理一些布局Ҏ(gu)卛_Q其中要实现的有以下几点Q?br />
1、英、中字体
很多中文字体中的英文字体都比较难看,所以在X的字体配|中讄?jin)一个字体顺序。我也可以学学,传递一个字体列表,拿到一个字W时Q按序从字体列表中查询Q查询不到时查下一个字体,q样可以实现英、中使用不同字体?jin)?br />
2、分?br />D落分行要考虑C、英文不同的分割方式Q还有标点符P某引h点符号不能在行尾Q比如?lt;{)(j)Q某些标点不能在行首Q比如?gt;Q,某些标点不能分割Q比如破折号Q,所以实际上要有一个分割算法,把段落分成一个个的标讎ͼ汉字直接分割Q英文按I格分割Q不能在行首的标点就分到前面单词里,不能在行分在后面的单词里?br />
3、对?br />寚w方式有左、中、右、两?Full Justification)q几U方式,目前大部分开源渲染库都不支持两端寚wQ这也是我要自己实现的主要原因。左、中、右只要计算Z行的所有字W宽度,再计出左边距即可。两端对齐则需要计每个单词的间距?br />
4、段首羃q?br /> 原来设想在分D后直接加上全角I格Q不惌个空格在转成UNICODE~码Ӟ它的~码是\u0000Q不能获取到全角I格的宽度。于是把它设成字体高度,看了(jin)一下效果还好?br />

qiezi 2006-10-09 11:44 发表评论
]]>
[private] 文字l图库资料收?/title><link>http://www.shnenglu.com/cpunion/archive/2006/09/28/13124.html</link><dc:creator>qiezi</dc:creator><author>qiezi</author><pubDate>Thu, 28 Sep 2006 12:03:00 GMT</pubDate><guid>http://www.shnenglu.com/cpunion/archive/2006/09/28/13124.html</guid><wfw:comment>http://www.shnenglu.com/cpunion/comments/13124.html</wfw:comment><comments>http://www.shnenglu.com/cpunion/archive/2006/09/28/13124.html#Feedback</comments><slash:comments>3</slash:comments><wfw:commentRss>http://www.shnenglu.com/cpunion/comments/commentRss/13124.html</wfw:commentRss><trackback:ping>http://www.shnenglu.com/cpunion/services/trackbacks/13124.html</trackback:ping><description><![CDATA[主要攉可以l制文字的绘囑ֺ?br /><br />一、imagemagick:<br />http://www.cit.gu.edu.au/~anthony/graphics/imagick6/<br />可以l制文字Q不q中文好像不能自动断行?br /><br />二、vips<br />http://vips.sourceforge.net<br />使用pangol制文字Q中文可以断行,~少2端对齐功能。自׃改代码增加了(jin)调整行距功能Q做成ruby扩展库,amd64上用失败,原因待查?br /><br />三、freetype<br />http://vips.sourceforge.net<br />不依赖其它图?H口库,其它不熟(zhn),待查?br /><br />四、Graphite<br />跨^台的字体渲染库。待查?br /><br /><br />搜寻已有数月Q目前看到的几个库都不太理想Qmac osx上可能比较专业,不过集成较困难?br /><br />Ҏ(gu)|站上的比较完整的字体绘制和布局斚w的资料:(x)<br />http://developer.apple.com/documentation/Carbon/Conceptual/ATSUI_Concepts/index.html<br />其中布局斚w的专业知识:(x)<br />http://developer.apple.com/documentation/Carbon/Conceptual/ATSUI_Concepts/atsui_chap3/chapter_3_section_3.html#//apple_ref/doc/uid/TP30000029-TPXREF157<br /><br /><br />其它资料Q?br /><ul><li><a title="Uniscribe">Uniscribe</a> (Windows multilingual text rendering engine)</li><li><a title="WorldScript">WorldScript</a> (Old Macintosh multilingual text rendering engine)</li><li><a title="Apple Type Services for Unicode Imaging">Apple Type Services for Unicode Imaging</a> (New Macintosh multilingual text rendering engine)</li></ul><br /><img src ="http://www.shnenglu.com/cpunion/aggbug/13124.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.shnenglu.com/cpunion/" target="_blank">qiezi</a> 2006-09-28 20:03 <a href="http://www.shnenglu.com/cpunion/archive/2006/09/28/13124.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[RoR] 实现一个auto_redirect_tohttp://www.shnenglu.com/cpunion/archive/2006/05/20/7434.htmlqieziqieziFri, 19 May 2006 18:33:00 GMThttp://www.shnenglu.com/cpunion/archive/2006/05/20/7434.htmlhttp://www.shnenglu.com/cpunion/comments/7434.htmlhttp://www.shnenglu.com/cpunion/archive/2006/05/20/7434.html#Feedback0http://www.shnenglu.com/cpunion/comments/commentRss/7434.htmlhttp://www.shnenglu.com/cpunion/services/trackbacks/7434.html
我遇到的一个问题是Q当使用Ajax更新面局部内Ҏ(gu)Qsession内容已经q期Q这旉要整个页面蟩转到d面?br />
直接调用redirect_to?x)局部内Ҏ(gu)C成d面Q它是在HTTP头里写入重定向参数来实现的。在我这里的Ҏ(gu)情况下,正确的做法是让它执行一个包含在<script>标记中的脚本Q在脚本中更改窗口location值来跌{?br />
不过RoR中用AjaxӞ?x)根?update参数来决定是使用Updaterq是Request。如果用Updater方式Q则应返回一D늺脚本Q如果是Request方式Q应q回一D包括在<script>标记中的脚本Q如果是普通方式,应该用原有的redirect_to函数?jin)。因为服务端无法区分使用的是哪种方式来请求,所以简单的做法是每个请求都附加一个参数用来区分,不加参数则是普通请求方式?br />
Z(jin)辑ֈq个目的Q我修改?jin)prototype_helper中的remote_function函数。这个函数根据传递进来的参数来决定用Request或是UpdaterQ我在q里下手Q?br />
 (tng) (tng) (tng) (tng) (tng) (tng)def (tng)remote_function(options)
 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)javascript_options (tng)
= (tng)options_for_ajax(options)

 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)update (tng)
= (tng)''
 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)
if (tng)options[:update] (tng)and (tng)options[:update].is_a?Hash
 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)update (tng) (tng)
= (tng)[]
 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)update (tng)
<< (tng)"success:'#{options[:update][:success]}'" (tng)if (tng)options[:update][:success]
 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)update (tng)
<< (tng)"failure:'#{options[:update][:failure]}'" (tng)if (tng)options[:update][:failure]
 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)update (tng) (tng)
= (tng)'{' (tng)+ (tng)update.join(',') (tng)+ (tng)'}'
 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)elsif (tng)options[:update]
 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)update (tng)
<< (tng)"'#{options[:update]}'"
 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)end

 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)function (tng)
= (tng)update.empty? (tng)? (tng)
 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)
"new (tng)Ajax.Request(" (tng):
 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)
"new (tng)Ajax.Updater(#{update}, (tng)"
 (tng) (tng) (tng) (tng)
 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)url_options (tng)
= (tng)options[:url]
 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)ajax_options (tng)
= (tng)options[:update] (tng)? (tng){:ajax (tng)=> (tng)'update'} (tng): (tng){:ajax (tng)=> (tng)'request'}
 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)url_options (tng)
=
 (tng)url_options.merge(ajax_options)
 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)url_options (tng)
= (tng)url_options.merge(:escape (tng)=> (tng)false) (tng)if (tng)url_options.is_a? (tng)Hash
 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)function (tng)
<< (tng)"'#{url_for(url_options)}'"
 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)function (tng)
<< (tng)", (tng)#{javascript_options})"

 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)function (tng)
= (tng)"#{options[:before]}; (tng)#{function}" (tng)if (tng)options[:before]
 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)function (tng)
= (tng)"#{function}; (tng)#{options[:after]}" (tng) (tng)if (tng)options[:after]
 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)function (tng)
= (tng)"if (tng)(#{options[:condition]}) (tng){ (tng)#{function}; (tng)}" (tng)if (tng)options[:condition]
 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)function (tng)
= (tng)"if (tng)(confirm('#{escape_javascript(options[:confirm])}')) (tng){ (tng)#{function}; (tng)}" (tng)if (tng)options[:confirm]

 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)
return (tng)function
 (tng) (tng) (tng) (tng) (tng) (tng)end

有红色的2行是我添加的Q由于这个编辑器的原因,没有昄成整行红艌Ӏ这2行的作用是判断是否有:update参数Q用它来军_是添加ajax=updateq是ajax=request?br />
现在可以实现一个简单的auto_redirect_to?jin)?x)

 (tng) (tng)def (tng)auto_redirect_to(method, (tng)url)
 (tng) (tng) (tng) (tng)
case (tng)method
 (tng) (tng) (tng) (tng)when (tng)
'request'
 (tng) (tng) (tng) (tng) (tng) (tng)request_redirect_to(url)
 (tng) (tng) (tng) (tng)when (tng)
'update'
 (tng) (tng) (tng) (tng) (tng) (tng)update_redirect_to(url)
 (tng) (tng) (tng) (tng)
else
 (tng) (tng) (tng) (tng) (tng) (tng)redirect_to(url)
 (tng) (tng) (tng) (tng)end
 (tng) (tng)end
 (tng) (tng)
 (tng) (tng)def (tng)request_redirect_to(url)
 (tng) (tng) (tng) (tng)render (tng):update (tng)
do (tng)|page|
 (tng) (tng) (tng) (tng) (tng) (tng)page.redirect_to(url)
 (tng) (tng) (tng) (tng)end
 (tng) (tng)end
 (tng) (tng)
 (tng) (tng)def (tng)update_redirect_to(url)
 (tng) (tng) (tng) (tng)render (tng):inline (tng)
=> (tng)<<-EOS
 (tng) (tng) (tng) (tng) (tng) (tng)
<script (tng)language="javascript">
 (tng) (tng) (tng) (tng) (tng) (tng)
<%=
 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)render (tng):update (tng)
do (tng)|page|
 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)page.redirect_to(
"#{url_for(url)}")
 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)end
 (tng) (tng) (tng) (tng) (tng) (tng)
%>
 (tng) (tng) (tng) (tng) (tng) (tng)
</script>
 (tng) (tng) (tng) (tng)EOS
 (tng) (tng)end

使用helper方式使它能够被include到ApplicationController中就行了(jin)?br />
Z(jin)不和参数l得太死Q这里把method作ؓ(f)参数p用者传入?br />
使用Ҏ(gu)Q以Login EngineZQ它在access_denied中处理蟩转。在ApplicationController中重写这个函敎ͼ(x)

 (tng) (tng) (tng) (tng)def (tng)access_denied
 (tng) (tng) (tng) (tng) (tng) (tng)auto_redirect_to(
params[:ajax], (tng):controller (tng)=> (tng)"/user", (tng):action (tng)=> (tng)"login")
 (tng) (tng) (tng) (tng) (tng) (tng)
false
 (tng) (tng) (tng) (tng)end (tng) (tng)

现在可以试?jin)。请求可以是普通的Q超链接Q,Updater方式Q请求到一个DIV里)(j)QRequest方式Q现在都能够跌{到正页面?br />
ajax参数通过hack库代码来实现Q对于用者来说基本上是透明的?br />

qiezi 2006-05-20 02:33 发表评论
]]>
[RoR] 在RoR中调?Net webservicehttp://www.shnenglu.com/cpunion/archive/2006/05/14/7138.htmlqieziqieziSun, 14 May 2006 12:08:00 GMThttp://www.shnenglu.com/cpunion/archive/2006/05/14/7138.htmlhttp://www.shnenglu.com/cpunion/comments/7138.htmlhttp://www.shnenglu.com/cpunion/archive/2006/05/14/7138.html#Feedback0http://www.shnenglu.com/cpunion/comments/commentRss/7138.htmlhttp://www.shnenglu.com/cpunion/services/trackbacks/7138.html
using (tng)System;
using (tng)System.Web;
using (tng)System.Web.Services;
using (tng)System.Web.Services.Protocols;

[WebService(Namespace (tng)
= (tng)"http://tempuri.org/")]
[WebServiceBinding(ConformsTo (tng)
= (tng)WsiProfiles.BasicProfile1_1)]
public (tng)class (tng)Service (tng): (tng)System.Web.Services.WebService
{
 (tng) (tng) (tng) (tng)[WebMethod]
 (tng) (tng) (tng) (tng)
public (tng)string (tng)HelloWorld(string (tng)name) (tng){
 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)
return (tng)"Hello, (tng)" (tng)+ (tng)name;
 (tng) (tng) (tng) (tng)}
 (tng) (tng) (tng) (tng)
}

在RoR目里,dapp/apis/test_api.rbQ?br />
class (tng)TestApi (tng)< (tng)ActionWebService::API::Base
 (tng) (tng)api_method (tng):HelloWorld, (tng):expects (tng)
=> (tng)[{:name (tng)=> (tng):string}], (tng):returns (tng)=> (tng)[:string]
end

q是RoR里面通用的webservice元信息描q?br />
dapp/controllers/test_controller.rb:

class (tng)TestController (tng)< (tng)ApplicationController
 (tng) (tng)web_client_api (tng):test, (tng):soap, (tng)
"http://localhost/test/Service.asmx", (tng)
 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng):namespace (tng)
=> (tng)"http://tempuri.org/",
 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng):soap_action_base (tng)
=> (tng)"http://tempuri.org",
 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng):driver_options
=>{:default_encodingstyle (tng)=> (tng)SOAP::EncodingStyle::ASPDotNetHandler::Namespace (tng)}

 (tng) (tng)
def (tng)hello
 (tng) (tng) (tng) (tng)render_text (tng)test.HelloWorld(
"Li (tng)Jie")
 (tng) (tng)end
end

:soap_action_base选项是一个修补,不加q个选项?x)生SOAPAction头错误?br />
q行服务器,在浏览器中访?test/helloQ发现名字ؓ(f)I。经q长旉调试Q发?Net在解析SOAP消息体时Q不能处理这U命名空_(d)(x)

 (tng) (tng) (tng) (tng)<n1:HelloWorld (tng)xmlns:n1="http://tempuri.org/"
 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)soap:encodingStyle
="http://schemas.xmlsoap.org/soap/encoding/">
 (tng) (tng) (tng) (tng) (tng) (tng)
<name (tng)xsi:type="xsd:string">Li Jie</name>
 (tng) (tng) (tng) (tng)
</n1:HelloWorld>

把n1Lp?jin)。不q这部分实现在rubylib/soap/rpc/proxy.rb里面Q实在不方便修改。ؓ(f)?jin)让q个试通过Q暂时做?jin)点修改?x)

 (tng) (tng)def (tng)route(req_header, (tng)req_body, (tng)reqopt, (tng)resopt)
 (tng) (tng) (tng) (tng)req_env (tng)
= (tng)::SOAP::SOAPEnvelope.new(req_header, (tng)req_body)
 (tng) (tng) (tng) (tng)unless (tng)reqopt[:envelopenamespace].nil?
 (tng) (tng) (tng) (tng) (tng) (tng)set_envelopenamespace(req_env, (tng)reqopt[:envelopenamespace])
 (tng) (tng) (tng) (tng)end
 (tng) (tng) (tng) (tng)reqopt[:external_content] (tng)
= (tng)nil
 (tng) (tng) (tng) (tng)conn_data (tng)
= (tng)marshal(req_env, (tng)reqopt)
 (tng) (tng) (tng) (tng)
if (tng)ext (tng)= (tng)reqopt[:external_content]
 (tng) (tng) (tng) (tng) (tng) (tng)mime (tng)
= (tng)MIMEMessage.new
 (tng) (tng) (tng) (tng) (tng) (tng)ext.each (tng)do (tng)
|k, (tng)v|
 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)mime.add_attachment(v.data)
 (tng) (tng) (tng) (tng) (tng) (tng)end
 (tng) (tng) (tng) (tng) (tng) (tng)mime.add_part(conn_data.send_string (tng)
+ (tng)"\r\n")
 (tng) (tng) (tng) (tng) (tng) (tng)mime.close
 (tng) (tng) (tng) (tng) (tng) (tng)conn_data.send_string (tng)
= (tng)mime.content_str
 (tng) (tng) (tng) (tng) (tng) (tng)conn_data.send_contenttype (tng)
= (tng)mime.headers['content-type'].str
 (tng) (tng) (tng) (tng)end

 (tng) (tng) (tng) (tng)conn_data.send_string.gsub!(
/:n1/, (tng)'')
 (tng) (tng) (tng) (tng)conn_data.send_string.gsub!(
/n1:/, (tng)''
)

 (tng) (tng) (tng) (tng)conn_data (tng)
= (tng)@streamhandler.send(@endpoint_url, (tng)conn_data,
 (tng) (tng) (tng) (tng) (tng) (tng)reqopt[:soapaction])
 (tng) (tng) (tng) (tng)
if (tng)conn_data.receive_string.empty?
 (tng) (tng) (tng) (tng) (tng) (tng)
return (tng)nil
 (tng) (tng) (tng) (tng)end
 (tng) (tng) (tng) (tng)unmarshal(conn_data, (tng)resopt)
 (tng) (tng)end

加粗?行是我添加的代码Q勉强可以让它工作,不过昄不是正确的方法?br />
不知道是不是.Net库里面的BUG?img src ="http://www.shnenglu.com/cpunion/aggbug/7138.html" width = "1" height = "1" />

qiezi 2006-05-14 20:08 发表评论
]]>
[RoR] 脚本模拟RJSh面http://www.shnenglu.com/cpunion/archive/2006/05/13/7087.htmlqieziqieziSat, 13 May 2006 15:49:00 GMThttp://www.shnenglu.com/cpunion/archive/2006/05/13/7087.htmlhttp://www.shnenglu.com/cpunion/comments/7087.htmlhttp://www.shnenglu.com/cpunion/archive/2006/05/13/7087.html#Feedback0http://www.shnenglu.com/cpunion/comments/commentRss/7087.htmlhttp://www.shnenglu.com/cpunion/services/trackbacks/7087.html
演示面直接在浏览器中观看?br />
演示下蝲

qiezi 2006-05-13 23:49 发表评论
]]>
[RoR] 用javascript脚本模拟一个actionhttp://www.shnenglu.com/cpunion/archive/2006/05/12/7046.htmlqieziqieziFri, 12 May 2006 15:41:00 GMThttp://www.shnenglu.com/cpunion/archive/2006/05/12/7046.htmlhttp://www.shnenglu.com/cpunion/comments/7046.htmlhttp://www.shnenglu.com/cpunion/archive/2006/05/12/7046.html#Feedback0http://www.shnenglu.com/cpunion/comments/commentRss/7046.htmlhttp://www.shnenglu.com/cpunion/services/trackbacks/7046.html
有些时候我们ƈ不需要请求服务器Q只惛_览器上执行某些脚本更新Q但又想使用RJS。所以ؓ(f)RoR增加?jin)这功能?br />
使用Ҏ(gu)Q?br />
<script (tng)language="javascript">
<%= (tng)
render (tng):update (tng)do (tng)
|page|
 (tng) (tng)page.define_action (tng)
'test_action' (tng)do
 (tng) (tng) (tng) (tng)page.call_script (tng)
<<-EOS
 (tng) (tng) (tng) (tng) (tng) (tng)alert(params.comment.title);
 (tng) (tng) (tng) (tng) (tng) (tng)alert(params.comment.body);
 (tng) (tng) (tng) (tng)EOS
 (tng) (tng) (tng) (tng)page.replace_html (tng)
'errors', (tng)'ERROR'
 (tng) (tng)end

 (tng) (tng)page.define_action (tng)
'link_action' (tng)do
 (tng) (tng) (tng) (tng)page.replace_html (tng)
'errors', (tng)'ERROR'
 (tng) (tng)end
end
%>
</script>

<div (tng)id="errors"></div>

<%= (tng)form_local_tag (tng):html (tng)=> (tng){:action (tng)=> (tng)'test_action'} (tng)%>
 (tng) (tng)
<input (tng)name="comment[title]" (tng)/><br (tng)/>
 (tng) (tng)
<input (tng)name="comment[body]" (tng)/><br (tng)/>
 (tng) (tng)
<%= (tng)submit_tag (tng)'Create' (tng)%>
<%= (tng)end_form_tag (tng)%>

<%= (tng)link_to_local (tng)'Test', (tng):action (tng)=> (tng)'link_action()' (tng)%>

上面演示?jin)form_local_tag和link_to_local的用,打开q个面以后Q可以关掉服务器试Q会(x)发现它不h服务器也能执行相应脚本?br />
define_action定义一个脚本函敎ͼcall_script用来实现javascript和RJS代码的؜合。当使用form_local_tagӞactionҎ(gu)的参数已l被处理q,所以可以直接在action中用params.comment.title?br />
当然现在q(sh)完善Q比如还只能使用转换完的面模板Q一些动态页面将看不出效果。要做到q点Q需要用javascript实现一整套的ActionView辅助Ҏ(gu)?br />
下面提供一个针对rails 1.1.2的一个补丁文Ӟ(x)

补丁文g下蝲

qiezi 2006-05-12 23:41 发表评论
]]>
[RoR] 单的角色权限(g)查插?/title><link>http://www.shnenglu.com/cpunion/archive/2006/05/08/6790.html</link><dc:creator>qiezi</dc:creator><author>qiezi</author><pubDate>Mon, 08 May 2006 13:30:00 GMT</pubDate><guid>http://www.shnenglu.com/cpunion/archive/2006/05/08/6790.html</guid><wfw:comment>http://www.shnenglu.com/cpunion/comments/6790.html</wfw:comment><comments>http://www.shnenglu.com/cpunion/archive/2006/05/08/6790.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.shnenglu.com/cpunion/comments/commentRss/6790.html</wfw:commentRss><trackback:ping>http://www.shnenglu.com/cpunion/services/trackbacks/6790.html</trackback:ping><description><![CDATA[代码比较单:(x)<br /><br /><div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><span style="COLOR: #000000">module (tng)ActionController (tng)</span><span style="COLOR: #008000">#</span><span style="COLOR: #008000">:nodoc:</span><span style="COLOR: #008000"><br /></span><span style="COLOR: #000000"><br /> (tng) (tng)class (tng)CheckGroupError (tng)</span><span style="COLOR: #000000"><</span><span style="COLOR: #000000"> (tng)ActionControllerError (tng)</span><span style="COLOR: #008000">#</span><span style="COLOR: #008000">:nodoc:</span><span style="COLOR: #008000"><br /></span><span style="COLOR: #000000"> (tng) (tng) (tng) (tng)attr_reader (tng)</span><span style="COLOR: #000000">:</span><span style="COLOR: #000000">group_name<br /> (tng) (tng) (tng) (tng)def (tng)initialize(group_name)<br /> (tng) (tng) (tng) (tng) (tng) (tng)</span><span style="COLOR: #800080">@group_name</span><span style="COLOR: #000000"> (tng)</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> (tng)group_name<br /> (tng) (tng) (tng) (tng)end<br /> (tng) (tng)end<br /> (tng) (tng)<br /> (tng) (tng)class (tng)CheckRoleError (tng)</span><span style="COLOR: #000000"><</span><span style="COLOR: #000000"> (tng)ActionControllerError (tng)</span><span style="COLOR: #008000">#</span><span style="COLOR: #008000">:nodoc:</span><span style="COLOR: #008000"><br /></span><span style="COLOR: #000000"> (tng) (tng) (tng) (tng)attr_reader (tng)</span><span style="COLOR: #000000">:</span><span style="COLOR: #000000">role_name<br /> (tng) (tng) (tng) (tng)def (tng)initialize(role_name)<br /> (tng) (tng) (tng) (tng) (tng) (tng)</span><span style="COLOR: #800080">@role_name</span><span style="COLOR: #000000"> (tng)</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> (tng)role_name<br /> (tng) (tng) (tng) (tng)end<br /> (tng) (tng)end<br /> (tng) (tng)<br /> (tng) (tng)class (tng)Base (tng)</span><span style="COLOR: #008000">#</span><span style="COLOR: #008000">:nodoc:</span><span style="COLOR: #008000"><br /></span><span style="COLOR: #000000"> (tng) (tng) (tng) (tng)def (tng)roles<br /> (tng) (tng) (tng) (tng) (tng) (tng)[]<br /> (tng) (tng) (tng) (tng)end<br /> (tng) (tng) (tng) (tng)<br /> (tng) (tng) (tng) (tng)def (tng)groups<br /> (tng) (tng) (tng) (tng) (tng) (tng)[]<br /> (tng) (tng) (tng) (tng)end<br /> (tng) (tng) (tng) (tng)<br /> (tng) (tng) (tng) (tng)def (tng)check_roles(</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">role_args)<br /> (tng) (tng) (tng) (tng) (tng) (tng)role_args</span><span style="COLOR: #000000">.</span><span style="COLOR: #0000ff">each</span><span style="COLOR: #000000"> (tng)</span><span style="COLOR: #0000ff">do</span><span style="COLOR: #000000"> (tng)</span><span style="COLOR: #000000">|</span><span style="COLOR: #000000">role</span><span style="COLOR: #000000">|</span><span style="COLOR: #000000"><br /> (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)check_role(role)<br /> (tng) (tng) (tng) (tng) (tng) (tng)end<br /> (tng) (tng) (tng) (tng)end<br /> (tng) (tng) (tng) (tng)<br /> (tng) (tng) (tng) (tng)def (tng)check_groups(</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">group_args)<br /> (tng) (tng) (tng) (tng) (tng) (tng)group_args</span><span style="COLOR: #000000">.</span><span style="COLOR: #0000ff">each</span><span style="COLOR: #000000"> (tng)</span><span style="COLOR: #0000ff">do</span><span style="COLOR: #000000"> (tng)</span><span style="COLOR: #000000">|</span><span style="COLOR: #000000">group</span><span style="COLOR: #000000">|</span><span style="COLOR: #000000"><br /> (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)check_group(group)<br /> (tng) (tng) (tng) (tng) (tng) (tng)end<br /> (tng) (tng) (tng) (tng)end<br /> (tng) (tng) (tng) (tng)<br /> (tng) (tng) (tng) (tng)def (tng)check_group(group)<br /> (tng) (tng) (tng) (tng) (tng) (tng)raise (tng)CheckGroupError</span><span style="COLOR: #000000">.</span><span style="COLOR: #000000">new(group</span><span style="COLOR: #000000">.</span><span style="COLOR: #000000">to_s) (tng)</span><span style="COLOR: #0000ff">unless</span><span style="COLOR: #000000"> (tng)groups()</span><span style="COLOR: #000000">.</span><span style="COLOR: #000000">include</span><span style="COLOR: #000000">?</span><span style="COLOR: #000000">(group</span><span style="COLOR: #000000">.</span><span style="COLOR: #000000">to_s)<br /> (tng) (tng) (tng) (tng)end<br /> (tng) (tng) (tng) (tng)<br /> (tng) (tng) (tng) (tng)def (tng)check_role(role)<br /> (tng) (tng) (tng) (tng) (tng) (tng)raise (tng)CheckRoleError</span><span style="COLOR: #000000">.</span><span style="COLOR: #000000">new(role</span><span style="COLOR: #000000">.</span><span style="COLOR: #000000">to_s) (tng) (tng) (tng)</span><span style="COLOR: #0000ff">unless</span><span style="COLOR: #000000"> (tng)roles()</span><span style="COLOR: #000000">.</span><span style="COLOR: #000000">include</span><span style="COLOR: #000000">?</span><span style="COLOR: #000000">(role</span><span style="COLOR: #000000">.</span><span style="COLOR: #000000">to_s) (tng) (tng) (tng) (tng) (tng) (tng)<br /> (tng) (tng) (tng) (tng)end<br /> (tng) (tng)end<br /> (tng) (tng)<br />end</span></div><br />只需要在ApplicationController中实现roles和groupsq?个方法,Ҏ(gu)据库模式没有M限制Q只要能保证q?个方法能够得到当前用L(fng)角色和组卛_?br /><br />?个checkҎ(gu)可用Q可L使用一个或多个?br /><br />单模拟测试一下:(x)<br /><br /><div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><span style="COLOR: #000000">class (tng)ApplicationController (tng)</span><span style="COLOR: #000000"><</span><span style="COLOR: #000000"> (tng)ActionController</span><span style="COLOR: #000000">::</span><span style="COLOR: #000000">Base<br /> (tng) (tng)def (tng)roles<br /> (tng) (tng) (tng) (tng)</span><span style="COLOR: #800080">%w</span><span style="COLOR: #000000">(add (tng)show)<br /> (tng) (tng)end<br /><br /> (tng) (tng)def (tng)groups<br /> (tng) (tng) (tng) (tng)</span><span style="COLOR: #800080">%w</span><span style="COLOR: #000000">(users)<br /> (tng) (tng)end<br />end</span></div><br /><div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><span style="COLOR: #000000">class (tng)TestController (tng)</span><span style="COLOR: #000000"><</span><span style="COLOR: #000000"> (tng)ApplicationController<br /> (tng) (tng)def (tng)test1<br /> (tng) (tng) (tng) (tng)check_role (tng)</span><span style="COLOR: #000000">:</span><span style="COLOR: #000000">add<br /> (tng) (tng) (tng) (tng)render_text (tng)</span><span style="FONT-WEIGHT: bold; COLOR: #000000">"</span><span style="FONT-WEIGHT: bold; COLOR: #000000">OK</span><span style="FONT-WEIGHT: bold; COLOR: #000000">"</span><span style="COLOR: #000000"><br /> (tng) (tng)end<br /><br /> (tng) (tng)def (tng)test2<br /> (tng) (tng) (tng) (tng)check_role (tng)</span><span style="COLOR: #000000">:</span><span style="COLOR: #000000">add<br /> (tng) (tng) (tng) (tng)check_group (tng)</span><span style="COLOR: #000000">:</span><span style="COLOR: #000000">users<br /> (tng) (tng) (tng) (tng)render_text (tng)</span><span style="FONT-WEIGHT: bold; COLOR: #000000">"</span><span style="FONT-WEIGHT: bold; COLOR: #000000">OK</span><span style="FONT-WEIGHT: bold; COLOR: #000000">"</span><span style="COLOR: #000000"><br /> (tng) (tng)end<br /><br /> (tng) (tng)def (tng)test3<br /> (tng) (tng) (tng) (tng)check_groups (tng)</span><span style="COLOR: #000000">:</span><span style="COLOR: #000000">admin</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000"> (tng)</span><span style="COLOR: #000000">:</span><span style="COLOR: #000000">users<br /> (tng) (tng) (tng) (tng)render_text (tng)</span><span style="FONT-WEIGHT: bold; COLOR: #000000">"</span><span style="FONT-WEIGHT: bold; COLOR: #000000">OK</span><span style="FONT-WEIGHT: bold; COLOR: #000000">"</span><span style="COLOR: #000000"><br /> (tng) (tng)end<br /><br /> (tng) (tng)def (tng)test4<br /> (tng) (tng) (tng) (tng)check_roles (tng)</span><span style="COLOR: #000000">:</span><span style="COLOR: #000000">add</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000"> (tng)</span><span style="COLOR: #000000">:</span><span style="COLOR: #000000">remove<br /> (tng) (tng) (tng) (tng)render_text (tng)</span><span style="FONT-WEIGHT: bold; COLOR: #000000">"</span><span style="FONT-WEIGHT: bold; COLOR: #000000">OK</span><span style="FONT-WEIGHT: bold; COLOR: #000000">"</span><span style="COLOR: #000000"><br /> (tng) (tng)end<br />end</span></div><br />其中Qtest1、test2都会(x)成功Q而test3和test4则会(x)p|昄异常Q只需要处理rescue_action把它修改q昄面卛_?img src ="http://www.shnenglu.com/cpunion/aggbug/6790.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.shnenglu.com/cpunion/" target="_blank">qiezi</a> 2006-05-08 21:30 <a href="http://www.shnenglu.com/cpunion/archive/2006/05/08/6790.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>CQ+实现单的cd?/title><link>http://www.shnenglu.com/cpunion/archive/2005/09/26/435.html</link><dc:creator>qiezi</dc:creator><author>qiezi</author><pubDate>Mon, 26 Sep 2005 09:31:00 GMT</pubDate><guid>http://www.shnenglu.com/cpunion/archive/2005/09/26/435.html</guid><wfw:comment>http://www.shnenglu.com/cpunion/comments/435.html</wfw:comment><comments>http://www.shnenglu.com/cpunion/archive/2005/09/26/435.html#Feedback</comments><slash:comments>9</slash:comments><wfw:commentRss>http://www.shnenglu.com/cpunion/comments/commentRss/435.html</wfw:commentRss><trackback:ping>http://www.shnenglu.com/cpunion/services/trackbacks/435.html</trackback:ping><description><![CDATA[很久以前看到有h问“如何在CQ+中实现动态加载类”时Q简单地做了(jin)一个?BR><BR>不过当时没有去考虑动态加载DLL的情c(din)?BR><BR>今天?A href="mailto:cpp@codingnow.com">cpp@codingnow.com</A>中也有h问到q个问题Q就把它l做完了(jin)?BR><BR>当然只是单地做到?jin)“从全局cd库中Q根据类名创建实例,支持动态DLL加蝲”,说得更明白点Q?BR><BR>在应用程序App1中,向全局cd库中注册一个类?Test"Q在另一个隐式链接的DLL中(即App1一启动加载的DLLQ,向全局cd库中注册另外几个cd。这时可以在App1中通过cd的名字生成实例?BR><BR>在另一个显式加载的DLL中(卌用LoadLibrary加蝲Q,向全局cd库中注册其它几个cd。这旉过LoadLibrary加蝲q个DLLQ就可以生成q几个类型的实例?jin)?BR><BR>q地方不能上传文Ӟ把代码贴一点吧Q?BR><BR>typelib.h文gQ?BR><BR> <DIV style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><SPAN style="COLOR: #000000">#ifndef __TYPE_LIB_H__<BR></SPAN><SPAN style="COLOR: #0000ff">#define</SPAN><SPAN style="COLOR: #000000"> __TYPE_LIB_H__</SPAN><SPAN style="COLOR: #000000"><BR><BR>typedef </SPAN><SPAN style="COLOR: #0000ff">void</SPAN><SPAN style="COLOR: #000000">*</SPAN><SPAN style="COLOR: #000000">(</SPAN><SPAN style="COLOR: #000000">*</SPAN><SPAN style="COLOR: #000000">CREATE_FUNC)();<BR>typedef </SPAN><SPAN style="COLOR: #0000ff">void</SPAN><SPAN style="COLOR: #000000">(</SPAN><SPAN style="COLOR: #000000">*</SPAN><SPAN style="COLOR: #000000">RELEASE_FUNC)(</SPAN><SPAN style="COLOR: #0000ff">void</SPAN><SPAN style="COLOR: #000000">*</SPAN><SPAN style="COLOR: #000000">);<BR><BR></SPAN><SPAN style="COLOR: #0000ff">void</SPAN><SPAN style="COLOR: #000000"> regtype (</SPAN><SPAN style="COLOR: #0000ff">const</SPAN><SPAN style="COLOR: #000000"> </SPAN><SPAN style="COLOR: #0000ff">char</SPAN><SPAN style="COLOR: #000000">*</SPAN><SPAN style="COLOR: #000000"> name, CREATE_FUNC cfunc, RELEASE_FUNC rfunc);<BR><BR></SPAN><SPAN style="COLOR: #0000ff">void</SPAN><SPAN style="COLOR: #000000">*</SPAN><SPAN style="COLOR: #000000"> createObject (</SPAN><SPAN style="COLOR: #0000ff">const</SPAN><SPAN style="COLOR: #000000"> </SPAN><SPAN style="COLOR: #0000ff">char</SPAN><SPAN style="COLOR: #000000">*</SPAN><SPAN style="COLOR: #000000"> name);<BR><BR></SPAN><SPAN style="COLOR: #0000ff">void</SPAN><SPAN style="COLOR: #000000"> releaseObject (</SPAN><SPAN style="COLOR: #0000ff">const</SPAN><SPAN style="COLOR: #000000"> </SPAN><SPAN style="COLOR: #0000ff">char</SPAN><SPAN style="COLOR: #000000">*</SPAN><SPAN style="COLOR: #000000"> name, </SPAN><SPAN style="COLOR: #0000ff">void</SPAN><SPAN style="COLOR: #000000">*</SPAN><SPAN style="COLOR: #000000"> p);<BR><BR></SPAN><SPAN style="COLOR: #0000ff">struct</SPAN><SPAN style="COLOR: #000000"> ITestInterface<BR>{<BR>    </SPAN><SPAN style="COLOR: #0000ff">virtual</SPAN><SPAN style="COLOR: #000000"> </SPAN><SPAN style="COLOR: #000000">~</SPAN><SPAN style="COLOR: #000000">ITestInterface () {}<BR>    </SPAN><SPAN style="COLOR: #0000ff">virtual</SPAN><SPAN style="COLOR: #000000"> </SPAN><SPAN style="COLOR: #0000ff">void</SPAN><SPAN style="COLOR: #000000"> print () </SPAN><SPAN style="COLOR: #0000ff">const</SPAN><SPAN style="COLOR: #000000"> </SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000"> </SPAN><SPAN style="COLOR: #000000">0</SPAN><SPAN style="COLOR: #000000">;<BR>};<BR><BR>template </SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #0000ff">class</SPAN><SPAN style="COLOR: #000000"> T</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000"><BR></SPAN><SPAN style="COLOR: #0000ff">void</SPAN><SPAN style="COLOR: #000000">*</SPAN><SPAN style="COLOR: #000000"> create ()<BR>{<BR>    </SPAN><SPAN style="COLOR: #0000ff">return</SPAN><SPAN style="COLOR: #000000"> </SPAN><SPAN style="COLOR: #0000ff">new</SPAN><SPAN style="COLOR: #000000"> T;<BR>}<BR><BR>template </SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #0000ff">class</SPAN><SPAN style="COLOR: #000000"> T</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000"><BR></SPAN><SPAN style="COLOR: #0000ff">void</SPAN><SPAN style="COLOR: #000000"> release (</SPAN><SPAN style="COLOR: #0000ff">void</SPAN><SPAN style="COLOR: #000000">*</SPAN><SPAN style="COLOR: #000000"> p)<BR>{<BR>    delete (T</SPAN><SPAN style="COLOR: #000000">*</SPAN><SPAN style="COLOR: #000000">)p;<BR>}<BR><BR></SPAN><SPAN style="COLOR: #0000ff">#endif</SPAN><SPAN style="COLOR: #000000"> </SPAN><SPAN style="COLOR: #008000">//</SPAN><SPAN style="COLOR: #008000"> __TYPE_LIB_H__</SPAN></DIV><BR>typelib.cpp文gQ?BR><BR> <DIV style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><SPAN style="COLOR: #000000">#include </SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">typelib.h</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000"><BR><BR>#include </SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #0000ff">string</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000"><BR>#include </SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #000000">map</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000"><BR></SPAN><SPAN style="COLOR: #0000ff">using</SPAN><SPAN style="COLOR: #000000"> </SPAN><SPAN style="COLOR: #0000ff">namespace</SPAN><SPAN style="COLOR: #000000"> std;<BR><BR></SPAN><SPAN style="COLOR: #0000ff">namespace</SPAN><SPAN style="COLOR: #000000"> TypeRegistry<BR>{<BR>    </SPAN><SPAN style="COLOR: #0000ff">static</SPAN><SPAN style="COLOR: #000000"> map </SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #000000"> </SPAN><SPAN style="COLOR: #0000ff">string</SPAN><SPAN style="COLOR: #000000">, pair</SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #000000">CREATE_FUNC, RELEASE_FUNC</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000"> </SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000">  types_info;<BR><BR>    template </SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #0000ff">class</SPAN><SPAN style="COLOR: #000000"> T</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000"><BR>    </SPAN><SPAN style="COLOR: #0000ff">void</SPAN><SPAN style="COLOR: #000000"> regType (</SPAN><SPAN style="COLOR: #0000ff">const</SPAN><SPAN style="COLOR: #000000"> </SPAN><SPAN style="COLOR: #0000ff">string</SPAN><SPAN style="COLOR: #000000">&</SPAN><SPAN style="COLOR: #000000"> name)<BR>    {<BR>        types_info.insert (make_pair(name, make_pair(create</SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #000000">T</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000">, release</SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #000000">T</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000">)));<BR>    }<BR>}<BR><BR></SPAN><SPAN style="COLOR: #0000ff">void</SPAN><SPAN style="COLOR: #000000"> regtype (</SPAN><SPAN style="COLOR: #0000ff">const</SPAN><SPAN style="COLOR: #000000"> </SPAN><SPAN style="COLOR: #0000ff">char</SPAN><SPAN style="COLOR: #000000">*</SPAN><SPAN style="COLOR: #000000"> name, CREATE_FUNC cfunc, RELEASE_FUNC rfunc)<BR>{<BR>    TypeRegistry::types_info.insert (make_pair(name, make_pair(cfunc, rfunc)));<BR>}<BR><BR></SPAN><SPAN style="COLOR: #0000ff">void</SPAN><SPAN style="COLOR: #000000">*</SPAN><SPAN style="COLOR: #000000"> createObject (</SPAN><SPAN style="COLOR: #0000ff">const</SPAN><SPAN style="COLOR: #000000"> </SPAN><SPAN style="COLOR: #0000ff">char</SPAN><SPAN style="COLOR: #000000">*</SPAN><SPAN style="COLOR: #000000"> name)<BR>{<BR>    map </SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #000000"> </SPAN><SPAN style="COLOR: #0000ff">string</SPAN><SPAN style="COLOR: #000000">, pair</SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #000000">CREATE_FUNC, RELEASE_FUNC</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000"> </SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000">::const_iterator iter;<BR>    iter </SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000"> TypeRegistry::types_info.find (name);<BR>    </SPAN><SPAN style="COLOR: #0000ff">if</SPAN><SPAN style="COLOR: #000000"> (iter </SPAN><SPAN style="COLOR: #000000">!=</SPAN><SPAN style="COLOR: #000000"> TypeRegistry::types_info.end ())<BR>        </SPAN><SPAN style="COLOR: #0000ff">return</SPAN><SPAN style="COLOR: #000000"> (</SPAN><SPAN style="COLOR: #000000">*</SPAN><SPAN style="COLOR: #000000">iter</SPAN><SPAN style="COLOR: #000000">-></SPAN><SPAN style="COLOR: #000000">second.first)();<BR>    </SPAN><SPAN style="COLOR: #0000ff">return</SPAN><SPAN style="COLOR: #000000"> NULL;<BR>}<BR><BR></SPAN><SPAN style="COLOR: #0000ff">void</SPAN><SPAN style="COLOR: #000000"> releaseObject (</SPAN><SPAN style="COLOR: #0000ff">const</SPAN><SPAN style="COLOR: #000000"> </SPAN><SPAN style="COLOR: #0000ff">char</SPAN><SPAN style="COLOR: #000000">*</SPAN><SPAN style="COLOR: #000000"> name, </SPAN><SPAN style="COLOR: #0000ff">void</SPAN><SPAN style="COLOR: #000000">*</SPAN><SPAN style="COLOR: #000000"> p)<BR>{<BR>    map </SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #000000"> </SPAN><SPAN style="COLOR: #0000ff">string</SPAN><SPAN style="COLOR: #000000">, pair</SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #000000">CREATE_FUNC, RELEASE_FUNC</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000"> </SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000">::const_iterator iter;<BR>    iter </SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000"> TypeRegistry::types_info.find (name);<BR>    </SPAN><SPAN style="COLOR: #0000ff">if</SPAN><SPAN style="COLOR: #000000"> (iter </SPAN><SPAN style="COLOR: #000000">!=</SPAN><SPAN style="COLOR: #000000"> TypeRegistry::types_info.end ())<BR>        (</SPAN><SPAN style="COLOR: #000000">*</SPAN><SPAN style="COLOR: #000000">iter</SPAN><SPAN style="COLOR: #000000">-></SPAN><SPAN style="COLOR: #000000">second.second)(p);<BR>}</SPAN></DIV><BR>把它~译成静(rn)态lib或DLLQ就可以使用?jin)?BR><BR>在那2个ؓ(f)我们提供cd的DLL中,DllMain函数中加入下面的代码Q?BR><BR> <DIV style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><SPAN style="COLOR: #008000">//</SPAN><SPAN style="COLOR: #008000"> FirstTest和SecondTest?个类?/SPAN><SPAN style="COLOR: #008000"><BR></SPAN><SPAN style="COLOR: #000000">regtype(</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">FirstTest</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">, create</SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #000000">FirstTest</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000">, release</SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #000000">FirstTest</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000">);<BR>regtype(</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">FirstTest</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">, create</SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #000000">SecondTest</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000">, release</SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #000000">SecondTest</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000">);</SPAN></DIV><BR>可以向全局cd库中注册cd。注意在cd库中是没有保存类信息的,所以最好是使用单根cd来做?BR><BR>下面是一Ҏ(gu)试代码:(x)<BR><BR> <DIV style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000"> main()<BR>{<BR>       </SPAN><SPAN style="COLOR: #008000">//</SPAN><SPAN style="COLOR: #008000"> E序启动时注册类型?BR>       </SPAN><SPAN style="COLOR: #008000">//</SPAN><SPAN style="COLOR: #008000"> 实际上启动时加载了(jin)另一个动态链接库Q那里面?个类型,所以现在有4个类?/SPAN><SPAN style="COLOR: #008000"><BR></SPAN><SPAN style="COLOR: #000000">       regtype (</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">MyTest</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">, create</SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #000000">MyTest</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000">, release</SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #000000">MyTest</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000">);<BR>       </SPAN><SPAN style="COLOR: #0000ff">while</SPAN><SPAN style="COLOR: #000000"> (</SPAN><SPAN style="COLOR: #000000">1</SPAN><SPAN style="COLOR: #000000">)<BR>       {<BR>               </SPAN><SPAN style="COLOR: #0000ff">string</SPAN><SPAN style="COLOR: #000000"> class_name;<BR>               cin </SPAN><SPAN style="COLOR: #000000">>></SPAN><SPAN style="COLOR: #000000"> class_name;<BR>               </SPAN><SPAN style="COLOR: #0000ff">if</SPAN><SPAN style="COLOR: #000000"> (class_name </SPAN><SPAN style="COLOR: #000000">==</SPAN><SPAN style="COLOR: #000000"> </SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">q</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">)<BR>                       </SPAN><SPAN style="COLOR: #0000ff">break</SPAN><SPAN style="COLOR: #000000">;<BR>               </SPAN><SPAN style="COLOR: #008000">//</SPAN><SPAN style="COLOR: #008000"> 当输入loadӞ把另一个动态链接库加蝲q来Q那个链接库中有2个类型,现在共有6个类型可用?/SPAN><SPAN style="COLOR: #008000"><BR></SPAN><SPAN style="COLOR: #000000">               </SPAN><SPAN style="COLOR: #0000ff">if</SPAN><SPAN style="COLOR: #000000"> (class_name </SPAN><SPAN style="COLOR: #000000">==</SPAN><SPAN style="COLOR: #000000"> </SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">load</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">)<BR>               {<BR>                       LoadLibrary(</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">typelibdll_test.dll</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">);<BR>                       </SPAN><SPAN style="COLOR: #0000ff">continue</SPAN><SPAN style="COLOR: #000000">;<BR>               }<BR>               ITestInterface</SPAN><SPAN style="COLOR: #000000">*</SPAN><SPAN style="COLOR: #000000"> test </SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000"> (ITestInterface</SPAN><SPAN style="COLOR: #000000">*</SPAN><SPAN style="COLOR: #000000">)createObject (class_name.c_str());<BR>               </SPAN><SPAN style="COLOR: #0000ff">if</SPAN><SPAN style="COLOR: #000000"> (</SPAN><SPAN style="COLOR: #000000">!</SPAN><SPAN style="COLOR: #000000">test)<BR>               {<BR>                       cout </SPAN><SPAN style="COLOR: #000000"><<</SPAN><SPAN style="COLOR: #000000"> </SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">This type not found</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000"> </SPAN><SPAN style="COLOR: #000000"><<</SPAN><SPAN style="COLOR: #000000"> endl;<BR>                       </SPAN><SPAN style="COLOR: #0000ff">continue</SPAN><SPAN style="COLOR: #000000">;<BR>               }<BR>               test</SPAN><SPAN style="COLOR: #000000">-></SPAN><SPAN style="COLOR: #000000">print ();<BR>               releaseObject (class_name.c_str(), test);<BR>       }<BR>       </SPAN><SPAN style="COLOR: #0000ff">return</SPAN><SPAN style="COLOR: #000000"> </SPAN><SPAN style="COLOR: #000000">0</SPAN><SPAN style="COLOR: #000000">;<BR>}<BR></SPAN></DIV><BR>q有一个没考虑的地方,是没有l它加锁Q因为有可能在一个线E中加蝲一个DLL?BR><BR>不过我还有些怀疑这东西是否真的有用Q?img src ="http://www.shnenglu.com/cpunion/aggbug/435.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.shnenglu.com/cpunion/" target="_blank">qiezi</a> 2005-09-26 17:31 <a href="http://www.shnenglu.com/cpunion/archive/2005/09/26/435.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>为CQ+实现一个IDL Q二Q?/title><link>http://www.shnenglu.com/cpunion/archive/2005/09/20/349.html</link><dc:creator>qiezi</dc:creator><author>qiezi</author><pubDate>Tue, 20 Sep 2005 14:34:00 GMT</pubDate><guid>http://www.shnenglu.com/cpunion/archive/2005/09/20/349.html</guid><wfw:comment>http://www.shnenglu.com/cpunion/comments/349.html</wfw:comment><comments>http://www.shnenglu.com/cpunion/archive/2005/09/20/349.html#Feedback</comments><slash:comments>6</slash:comments><wfw:commentRss>http://www.shnenglu.com/cpunion/comments/commentRss/349.html</wfw:commentRss><trackback:ping>http://www.shnenglu.com/cpunion/services/trackbacks/349.html</trackback:ping><description><![CDATA[<P>说明Q?BR>要看懂后面那部分代码Q即使用Typelist的部分,最好预先看q《CQ+设计新思维》,英文版名为《Modern C++ Design》?BR>If模板cd写完后想h好像在哪见过Q早晨去公司查阅?jin)一下,在《生式~程——方法、工具与应用》一书中有讲Q英文名为《Generative Programming -- Methods, Tools, and Applications》基本和本篇中一个样?BR><BR><BR>?ؕ七八p地讲了(jin)一些,有一个遗留问题,函数原型的推对{?BR><BR>要描q如下:(x)</P> <DIV style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><SPAN style="COLOR: #000000">Method </SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #000000"> </SPAN><SPAN style="COLOR: #0000ff">void</SPAN><SPAN style="COLOR: #000000">(</SPAN><SPAN style="COLOR: #0000ff">in</SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000">, </SPAN><SPAN style="COLOR: #0000ff">in</SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #0000ff">char</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000">, inout</SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #0000ff">string</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000">, </SPAN><SPAN style="COLOR: #0000ff">out</SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #0000ff">short</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000">) </SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000"> method;<BR><BR></SPAN><SPAN style="COLOR: #008000">//</SPAN><SPAN style="COLOR: #008000"> 同步调用</SPAN><SPAN style="COLOR: #008000"><BR></SPAN><SPAN style="COLOR: #0000ff">string</SPAN><SPAN style="COLOR: #000000"> str </SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000"> </SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">hello</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">;<BR></SPAN><SPAN style="COLOR: #0000ff">short</SPAN><SPAN style="COLOR: #000000"> value </SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000"> </SPAN><SPAN style="COLOR: #000000">2</SPAN><SPAN style="COLOR: #000000">;<BR>method (</SPAN><SPAN style="COLOR: #000000">3</SPAN><SPAN style="COLOR: #000000">, </SPAN><SPAN style="COLOR: #000000">'</SPAN><SPAN style="COLOR: #000000">a</SPAN><SPAN style="COLOR: #000000">'</SPAN><SPAN style="COLOR: #000000">, str, value</SPAN><SPAN style="COLOR: #000000">);<BR><BR></SPAN><SPAN style="COLOR: #008000">//</SPAN><SPAN style="COLOR: #008000"> 异步调用1</SPAN><SPAN style="COLOR: #008000"><BR></SPAN><SPAN style="COLOR: #000000">method.async_call (</SPAN><SPAN style="COLOR: #000000">3</SPAN><SPAN style="COLOR: #000000">, </SPAN><SPAN style="COLOR: #000000">'</SPAN><SPAN style="COLOR: #000000">a</SPAN><SPAN style="COLOR: #000000">'</SPAN><SPAN style="COLOR: #000000">, </SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">hello</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">);<BR><BR></SPAN><SPAN style="COLOR: #008000">//</SPAN><SPAN style="COLOR: #008000"> 异步调用2</SPAN><SPAN style="COLOR: #008000"><BR></SPAN><SPAN style="COLOR: #0000ff">void</SPAN><SPAN style="COLOR: #000000"> test_func (</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">, </SPAN><SPAN style="COLOR: #0000ff">char</SPAN><SPAN style="COLOR: #000000">, </SPAN><SPAN style="COLOR: #0000ff">string</SPAN><SPAN style="COLOR: #000000">, </SPAN><SPAN style="COLOR: #0000ff">short</SPAN><SPAN style="COLOR: #000000">);<BR>method.async_call (</SPAN><SPAN style="COLOR: #000000">3</SPAN><SPAN style="COLOR: #000000">, </SPAN><SPAN style="COLOR: #000000">'</SPAN><SPAN style="COLOR: #000000">a</SPAN><SPAN style="COLOR: #000000">'</SPAN><SPAN style="COLOR: #000000">, </SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">hello</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">, test_func);</SPAN></DIV> <P><BR>要生这3U函数Ş式。参数类型如何{换,是以后的话题Q本主要解军_步调用的函数原Ş推导问题。本也不讨论Method的模板参敎ͼ即那个函数类型)(j)q回cd不ؓ(f)void的情c(din)?BR><BR>W一UŞ式,同步调用Q比较好处理Q参C数和模板参数的数量相同?BR><BR>?UŞ式,如何让编译器Ҏ(gu)in/out来推导出函数原型Q?BR><BR>我们需要编译器做这L(fng)处理Qasync_call的参数类型中Qincd的参数将保留Qoutcd的参C需要,inoutcd也需要保留?BR><BR>要用到的Loki头文Ӟ(x)</P> <DIV style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><SPAN style="COLOR: #000000">#include </SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #000000">static_check.h</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000"><BR>#include </SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #000000">Typelist.h</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000"><BR><BR></SPAN><SPAN style="COLOR: #0000ff">using</SPAN><SPAN style="COLOR: #000000"> </SPAN><SPAN style="COLOR: #0000ff">namespace</SPAN><SPAN style="COLOR: #000000"> Loki;<BR></SPAN><SPAN style="COLOR: #0000ff">using</SPAN><SPAN style="COLOR: #000000"> </SPAN><SPAN style="COLOR: #0000ff">namespace</SPAN><SPAN style="COLOR: #000000"> Loki::TL;</SPAN></DIV> <P><BR>首先看看in/inout/out的声明。ؓ(f)?jin)简化,q里L?jin)跟cd推导无关的部分?/P> <DIV style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><SPAN style="COLOR: #0000ff">class</SPAN><SPAN style="COLOR: #000000"> NullType<BR>{<BR>    NullType ();<BR>};<BR><BR>template </SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #0000ff">class</SPAN><SPAN style="COLOR: #000000"> T</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000"><BR></SPAN><SPAN style="COLOR: #0000ff">struct</SPAN><SPAN style="COLOR: #000000"> </SPAN><SPAN style="COLOR: #0000ff">in</SPAN><SPAN style="COLOR: #000000"><BR>{<BR>    typedef T OriginalType;<BR>};<BR><BR>template </SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #0000ff">class</SPAN><SPAN style="COLOR: #000000"> T</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000"><BR></SPAN><SPAN style="COLOR: #0000ff">struct</SPAN><SPAN style="COLOR: #000000"> </SPAN><SPAN style="COLOR: #0000ff">out</SPAN><SPAN style="COLOR: #000000"><BR>{<BR>    typedef T OriginalType;<BR>};<BR><BR>template </SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #0000ff">class</SPAN><SPAN style="COLOR: #000000"> T</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000"><BR></SPAN><SPAN style="COLOR: #0000ff">struct</SPAN><SPAN style="COLOR: #000000"> inout<BR>{<BR>    typedef T OriginalType;<BR>};<BR></SPAN></DIV><BR>下面Method模板cȝ声明Q用偏特化来生代码。ؓ(f)?jin)简化,我只取函数参CCؓ(f)4个参数的版本Q比照着上面的代码来解释Q只解释method.async_call (3, 'a', "hello", test_func);q个版本Q因为另一个比它简单?BR><BR> <DIV style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><SPAN style="COLOR: #000000">template </SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #0000ff">class</SPAN><SPAN style="COLOR: #000000"> T</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000"><BR></SPAN><SPAN style="COLOR: #0000ff">struct</SPAN><SPAN style="COLOR: #000000"> Method<BR>{<BR>};<BR><BR>template </SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #0000ff">class</SPAN><SPAN style="COLOR: #000000"> Ret, </SPAN><SPAN style="COLOR: #0000ff">class</SPAN><SPAN style="COLOR: #000000"> A, </SPAN><SPAN style="COLOR: #0000ff">class</SPAN><SPAN style="COLOR: #000000"> B, </SPAN><SPAN style="COLOR: #0000ff">class</SPAN><SPAN style="COLOR: #000000"> C, </SPAN><SPAN style="COLOR: #0000ff">class</SPAN><SPAN style="COLOR: #000000"> D</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000"><BR></SPAN><SPAN style="COLOR: #0000ff">struct</SPAN><SPAN style="COLOR: #000000"> Method </SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #000000">Ret(A,B,C,D)</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000"> <BR>{<BR>};</SPAN></DIV> <P><BR>Ҏ(gu)上面Method的定义,Method < void(in<INT>, in<CHAR>, inout<STRING>, out<SHORT>) > Qasync_call函数的类型将是:(x)<SPAN style="COLOR: #000000"></P> <DIV style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><SPAN style="COLOR: #000000">typedef </SPAN><SPAN style="COLOR: #0000ff">void</SPAN><SPAN style="COLOR: #000000"> (</SPAN><SPAN style="COLOR: #000000">*</SPAN><SPAN style="COLOR: #000000">FUNC_TYPE)(</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">, </SPAN><SPAN style="COLOR: #0000ff">char</SPAN><SPAN style="COLOR: #000000">, </SPAN><SPAN style="COLOR: #0000ff">string</SPAN><SPAN style="COLOR: #000000">, </SPAN><SPAN style="COLOR: #0000ff">short</SPAN><SPAN style="COLOR: #000000">);<BR></SPAN><SPAN style="COLOR: #0000ff">void</SPAN><SPAN style="COLOR: #000000"> async_call (</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">, </SPAN><SPAN style="COLOR: #0000ff">char</SPAN><SPAN style="COLOR: #000000">, </SPAN><SPAN style="COLOR: #0000ff">string</SPAN><SPAN style="COLOR: #000000">, FUNC_TYPE func);</SPAN></DIV></SPAN><BR>实际上FUNC_TYPE应该能够接受更广泛的cdQ比如void(int, char, char*, short)Q这可以在内部做一些{换,不过本篇的重点不在这里,所以只讲上面的那种形式?BR><BR>直接在MethodcM实现有些ȝ(ch)Q所以我把这个函数放在一个基cM实现Q只要编译器能帮我们推导Z面这UŞ式就行了(jin)Q?BR><BR> <DIV style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><SPAN style="COLOR: #000000">template </SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #0000ff">class</SPAN><SPAN style="COLOR: #000000"> Ret, </SPAN><SPAN style="COLOR: #0000ff">class</SPAN><SPAN style="COLOR: #000000"> A, </SPAN><SPAN style="COLOR: #0000ff">class</SPAN><SPAN style="COLOR: #000000"> B, </SPAN><SPAN style="COLOR: #0000ff">class</SPAN><SPAN style="COLOR: #000000"> C, </SPAN><SPAN style="COLOR: #0000ff">class</SPAN><SPAN style="COLOR: #000000"> D</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000"><BR></SPAN><SPAN style="COLOR: #0000ff">struct</SPAN><SPAN style="COLOR: #000000"> Method </SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #000000">Ret(A,B,C,D)</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000"> : </SPAN><SPAN style="COLOR: #0000ff">public</SPAN><SPAN style="COLOR: #000000"> Base </SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #000000"> A, B, C </SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000"><BR>{<BR>};</SPAN></DIV> <P><BR>注意Q这里是以Method < void(in<INT>, in<CHAR>, inout<STRING>, out<SHORT>) >q种形式来讲的,才会(x)有上面那U承关pR而实际上Q由于in/out在参C的位|、数量都是未知的Q要到定义时才能定Q所以用模板来推导。(入正题(sh)(jin)Q?/P> <P>也就是说Q只要我们能使用?rn)态推导方式,获得A,B,C,Dq四个参C所有的incdQ把它交lBase作ؓ(f)模板参数成?jin)?/P> <P>q里需要一个辅助的模板c,用来在编译时帮助推导Q?BR><BR></P> <DIV style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><SPAN style="COLOR: #000000">template </SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #0000ff">class</SPAN><SPAN style="COLOR: #000000"> T</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000"><BR></SPAN><SPAN style="COLOR: #0000ff">class</SPAN><SPAN style="COLOR: #000000"> InOutTypeTraits<BR>{<BR>    Loki::CompileTimeError </SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #0000ff">false</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000"> Not_Supported_Type;<BR>};<BR><BR>template </SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #0000ff">class</SPAN><SPAN style="COLOR: #000000"> T</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000"><BR></SPAN><SPAN style="COLOR: #0000ff">struct</SPAN><SPAN style="COLOR: #000000"> InOutTypeTraits </SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #000000"> </SPAN><SPAN style="COLOR: #0000ff">in</SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #000000">T</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000"> </SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000"><BR>{<BR>    </SPAN><SPAN style="COLOR: #0000ff">enum</SPAN><SPAN style="COLOR: #000000"> {isin</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">1</SPAN><SPAN style="COLOR: #000000">, isout</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">0</SPAN><SPAN style="COLOR: #000000">};<BR>};<BR><BR>template </SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #0000ff">class</SPAN><SPAN style="COLOR: #000000"> T</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000"><BR></SPAN><SPAN style="COLOR: #0000ff">struct</SPAN><SPAN style="COLOR: #000000"> InOutTypeTraits </SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #000000"> </SPAN><SPAN style="COLOR: #0000ff">out</SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #000000">T</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000"> </SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000"><BR>{<BR>    </SPAN><SPAN style="COLOR: #0000ff">enum</SPAN><SPAN style="COLOR: #000000"> {isin</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">0</SPAN><SPAN style="COLOR: #000000">, isout</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">1</SPAN><SPAN style="COLOR: #000000">};<BR>};<BR><BR>template </SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #0000ff">class</SPAN><SPAN style="COLOR: #000000"> T</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000"><BR></SPAN><SPAN style="COLOR: #0000ff">struct</SPAN><SPAN style="COLOR: #000000"> InOutTypeTraits </SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #000000"> inout</SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #000000">T</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000"> </SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000"><BR>{<BR>    </SPAN><SPAN style="COLOR: #0000ff">enum</SPAN><SPAN style="COLOR: #000000"> {isin</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">1</SPAN><SPAN style="COLOR: #000000">, isout</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">1</SPAN><SPAN style="COLOR: #000000">};<BR>};<BR><BR>template </SPAN><SPAN style="COLOR: #000000"><></SPAN><SPAN style="COLOR: #000000"><BR></SPAN><SPAN style="COLOR: #0000ff">struct</SPAN><SPAN style="COLOR: #000000"> InOutTypeTraits </SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #000000"> NullType </SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000"><BR>{<BR>    </SPAN><SPAN style="COLOR: #0000ff">enum</SPAN><SPAN style="COLOR: #000000"> {isin</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">0</SPAN><SPAN style="COLOR: #000000">, isout</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">0</SPAN><SPAN style="COLOR: #000000">};<BR>};</SPAN></DIV></SPAN><BR>通过另一个模板类InList来帮我们产生所有的incdQ它的结果是一个Typelist。ؓ(f)?jin)方便以后用,我把outcd产生器也做了(jin)一个OutList?BR><BR> <DIV style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><SPAN style="COLOR: #000000">template </SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000"> CONDITION, </SPAN><SPAN style="COLOR: #0000ff">class</SPAN><SPAN style="COLOR: #000000"> _IF, </SPAN><SPAN style="COLOR: #0000ff">class</SPAN><SPAN style="COLOR: #000000"> _ELSE</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000"><BR></SPAN><SPAN style="COLOR: #0000ff">struct</SPAN><SPAN style="COLOR: #000000"> If<BR>{<BR>    typedef _IF Result;<BR>};<BR><BR>template </SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #0000ff">class</SPAN><SPAN style="COLOR: #000000"> _IF, </SPAN><SPAN style="COLOR: #0000ff">class</SPAN><SPAN style="COLOR: #000000"> _ELSE</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000"><BR></SPAN><SPAN style="COLOR: #0000ff">struct</SPAN><SPAN style="COLOR: #000000"> If </SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #000000">0</SPAN><SPAN style="COLOR: #000000">, _IF, _ELSE</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000"><BR>{<BR>    typedef _ELSE Result;<BR>};<BR><BR>template </SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #0000ff">class</SPAN><SPAN style="COLOR: #000000"> A </SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000"> NullType, </SPAN><SPAN style="COLOR: #0000ff">class</SPAN><SPAN style="COLOR: #000000"> B </SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000"> NullType, </SPAN><SPAN style="COLOR: #0000ff">class</SPAN><SPAN style="COLOR: #000000"> C </SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000"> NullType, </SPAN><SPAN style="COLOR: #0000ff">class</SPAN><SPAN style="COLOR: #000000"> D </SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000"> NullType, <BR>    </SPAN><SPAN style="COLOR: #0000ff">class</SPAN><SPAN style="COLOR: #000000"> E </SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000"> NullType, </SPAN><SPAN style="COLOR: #0000ff">class</SPAN><SPAN style="COLOR: #000000"> F </SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000"> NullType, </SPAN><SPAN style="COLOR: #0000ff">class</SPAN><SPAN style="COLOR: #000000"> G </SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000"> NullType, </SPAN><SPAN style="COLOR: #0000ff">class</SPAN><SPAN style="COLOR: #000000"> H </SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000"> NullType<BR></SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000"><BR></SPAN><SPAN style="COLOR: #0000ff">struct</SPAN><SPAN style="COLOR: #000000"> InList<BR>{<BR>    typedef typename If </SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #000000"> <BR>        InOutTypeTraits </SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #000000">A</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000">::isin,<BR>        typename Typelist </SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #000000"> A, typename InList</SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #000000">B,C,D,E,F,G</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000">::Result </SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000">, <BR>        typename InList</SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #000000">B,C,D,E,F,G,H</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000">::Result <BR>    </SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000">::Result Result;<BR>};<BR><BR>template </SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #0000ff">class</SPAN><SPAN style="COLOR: #000000"> A</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000"><BR></SPAN><SPAN style="COLOR: #0000ff">struct</SPAN><SPAN style="COLOR: #000000"> InList </SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #000000">A, NullType, NullType, NullType, NullType, NullType, NullType, NullType</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000"><BR>{<BR>    typedef typename If </SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #000000"><BR>        InOutTypeTraits </SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #000000">A</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000">::isin,<BR>        typename MakeTypelist </SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #000000">A</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000">::Result,<BR>        typename MakeTypelist </SPAN><SPAN style="COLOR: #000000"><></SPAN><SPAN style="COLOR: #000000">::Result<BR>    </SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000">::Result Result;<BR>};<BR><BR>template </SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #0000ff">class</SPAN><SPAN style="COLOR: #000000"> A </SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000"> NullType, </SPAN><SPAN style="COLOR: #0000ff">class</SPAN><SPAN style="COLOR: #000000"> B </SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000"> NullType, </SPAN><SPAN style="COLOR: #0000ff">class</SPAN><SPAN style="COLOR: #000000"> C </SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000"> NullType, </SPAN><SPAN style="COLOR: #0000ff">class</SPAN><SPAN style="COLOR: #000000"> D </SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000"> NullType, <BR>    </SPAN><SPAN style="COLOR: #0000ff">class</SPAN><SPAN style="COLOR: #000000"> E </SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000"> NullType, </SPAN><SPAN style="COLOR: #0000ff">class</SPAN><SPAN style="COLOR: #000000"> F </SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000"> NullType, </SPAN><SPAN style="COLOR: #0000ff">class</SPAN><SPAN style="COLOR: #000000"> G </SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000"> NullType, </SPAN><SPAN style="COLOR: #0000ff">class</SPAN><SPAN style="COLOR: #000000"> H </SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000"> NullType<BR></SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000"><BR></SPAN><SPAN style="COLOR: #0000ff">struct</SPAN><SPAN style="COLOR: #000000"> OutList<BR>{<BR>    typedef typename If </SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #000000"> <BR>        InOutTypeTraits</SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #000000">A</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000">::isout,<BR>        typename Typelist </SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #000000"> A, typename OutList</SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #000000">B,C,D,E,F,G</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000">::Result </SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000">, <BR>        typename OutList</SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #000000">B,C,D,E,F,G,H</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000">::Result <BR>    </SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000">::Result Result;<BR>};<BR><BR>template </SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #0000ff">class</SPAN><SPAN style="COLOR: #000000"> A</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000"><BR></SPAN><SPAN style="COLOR: #0000ff">struct</SPAN><SPAN style="COLOR: #000000"> OutList </SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #000000">A, NullType, NullType, NullType, NullType, NullType, NullType, NullType</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000"><BR>{<BR>    typedef typename MakeTypelist </SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #000000">A</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000">::Result Result;<BR>};</SPAN></DIV><BR>它的原理是,Ҏ(gu)If模板cL判断一个类型是不是incdQ是的话把它加入到Typelist中,不是排除它?BR><BR>InList <IN<INT>, in<CHAR>, inout<STRING>, out<SHORT>::Result是一个Typelist <IN<INT>, Typelist<IN<CHAR>, Typelist<INOUT<STRING>, NullType> > >cdQ说单点Q它和MakeTypelist < in<INT>, in<CHAR>, inout<STIRNG> >::Result是等L(fng)?BR><BR>现在Base模板cd接受一个模板参敎ͼ它是一个TypelistcdQ这个不详细讲了(jin)Q把它的定义写出来:(x)<BR><BR> <DIV style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><SPAN style="COLOR: #000000">template </SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #0000ff">class</SPAN><SPAN style="COLOR: #000000"> T, </SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000"> T_COUNT </SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000"> Length </SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #000000">IN_TYPE</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000">::value </SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000"><BR></SPAN><SPAN style="COLOR: #0000ff">struct</SPAN><SPAN style="COLOR: #000000"> Base<BR>{<BR>    Loki::CompileTimeError </SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #0000ff">false</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000"> Only_Use_Partial_Specialisation_Version;<BR>};<BR><BR>template </SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #0000ff">class</SPAN><SPAN style="COLOR: #000000"> T</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000"><BR></SPAN><SPAN style="COLOR: #0000ff">struct</SPAN><SPAN style="COLOR: #000000"> Base </SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #000000">T, </SPAN><SPAN style="COLOR: #000000">0</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000"><BR>{<BR>    typedef </SPAN><SPAN style="COLOR: #0000ff">void</SPAN><SPAN style="COLOR: #000000">(</SPAN><SPAN style="COLOR: #000000">*</SPAN><SPAN style="COLOR: #000000">FUNC_TYPE)();<BR><BR>    template </SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #0000ff">class</SPAN><SPAN style="COLOR: #000000"> FUNC_TYPE</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000"><BR>    </SPAN><SPAN style="COLOR: #0000ff">void</SPAN><SPAN style="COLOR: #000000"> async_call (FUNC_TYPE func)<BR>    {<BR>    }<BR>    </SPAN><SPAN style="COLOR: #0000ff">void</SPAN><SPAN style="COLOR: #000000"> async_call ()<BR>    {<BR>    }<BR>};<BR><BR>template </SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #0000ff">class</SPAN><SPAN style="COLOR: #000000"> T</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000"><BR></SPAN><SPAN style="COLOR: #0000ff">struct</SPAN><SPAN style="COLOR: #000000"> Base </SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #000000">T, </SPAN><SPAN style="COLOR: #000000">1</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000"><BR>{<BR>    typedef </SPAN><SPAN style="COLOR: #0000ff">void</SPAN><SPAN style="COLOR: #000000">(</SPAN><SPAN style="COLOR: #000000">*</SPAN><SPAN style="COLOR: #000000">FUNC_TYPE)(<BR>        typename TypeAt </SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #000000">T, </SPAN><SPAN style="COLOR: #000000">0</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000">::Result::OriginalType);<BR><BR>    </SPAN><SPAN style="COLOR: #0000ff">void</SPAN><SPAN style="COLOR: #000000"> async_call (<BR>        typename TypeAt </SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #000000">T, </SPAN><SPAN style="COLOR: #000000">0</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000">::Result::OriginalType v0,<BR>        FUNC_TYPE func)<BR>    {<BR>    }<BR>    </SPAN><SPAN style="COLOR: #0000ff">void</SPAN><SPAN style="COLOR: #000000"> async_call (typename TypeAt </SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #000000">T, </SPAN><SPAN style="COLOR: #000000">0</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000">::Result::OriginalType v0)<BR>    {<BR>    }<BR>};<BR><BR>template </SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #0000ff">class</SPAN><SPAN style="COLOR: #000000"> T</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000"><BR></SPAN><SPAN style="COLOR: #0000ff">struct</SPAN><SPAN style="COLOR: #000000"> Base </SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #000000">T, </SPAN><SPAN style="COLOR: #000000">2</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000"><BR>{<BR>    typedef </SPAN><SPAN style="COLOR: #0000ff">void</SPAN><SPAN style="COLOR: #000000">(</SPAN><SPAN style="COLOR: #000000">*</SPAN><SPAN style="COLOR: #000000">FUNC_TYPE)(<BR>        typename TypeAt </SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #000000">T, </SPAN><SPAN style="COLOR: #000000">0</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000">::Result::OriginalType,<BR>        typename TypeAt </SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #000000">T, </SPAN><SPAN style="COLOR: #000000">1</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000">::Result::OriginalType);<BR><BR>    </SPAN><SPAN style="COLOR: #0000ff">void</SPAN><SPAN style="COLOR: #000000"> async_call (<BR>        typename TypeAt </SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #000000">T, </SPAN><SPAN style="COLOR: #000000">0</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000">::Result::OriginalType v0, <BR>        typename TypeAt </SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #000000">T, </SPAN><SPAN style="COLOR: #000000">1</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000">::Result::OriginalType v1, <BR>        FUNC_TYPE func)<BR>    {<BR>    }<BR>    </SPAN><SPAN style="COLOR: #0000ff">void</SPAN><SPAN style="COLOR: #000000"> async_call (<BR>        typename TypeAt </SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #000000">T, </SPAN><SPAN style="COLOR: #000000">0</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000">::Result::OriginalType v0, <BR>        typename TypeAt </SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #000000">T, </SPAN><SPAN style="COLOR: #000000">1</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000">::Result::OriginalType v1)<BR>    {<BR>    }<BR>};<BR><BR>template </SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #0000ff">class</SPAN><SPAN style="COLOR: #000000"> T</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000"><BR></SPAN><SPAN style="COLOR: #0000ff">struct</SPAN><SPAN style="COLOR: #000000"> Base </SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #000000">T, </SPAN><SPAN style="COLOR: #000000">3</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000"><BR>{<BR>    typedef </SPAN><SPAN style="COLOR: #0000ff">void</SPAN><SPAN style="COLOR: #000000">(</SPAN><SPAN style="COLOR: #000000">*</SPAN><SPAN style="COLOR: #000000">FUNC_TYPE)(<BR>        typename TypeAt </SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #000000">T, </SPAN><SPAN style="COLOR: #000000">0</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000">::Result::OriginalType, <BR>        typename TypeAt </SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #000000">T, </SPAN><SPAN style="COLOR: #000000">1</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000">::Result::OriginalType,<BR>        typename TypeAt </SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #000000">T, </SPAN><SPAN style="COLOR: #000000">2</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000">::Result::OriginalType);<BR><BR>    </SPAN><SPAN style="COLOR: #0000ff">void</SPAN><SPAN style="COLOR: #000000"> async_call (<BR>        typename TypeAt </SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #000000">T, </SPAN><SPAN style="COLOR: #000000">0</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000">::Result::OriginalType v0, <BR>        typename TypeAt </SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #000000">T, </SPAN><SPAN style="COLOR: #000000">1</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000">::Result::OriginalType v1, <BR>        typename TypeAt </SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #000000">T, </SPAN><SPAN style="COLOR: #000000">2</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000">::Result::OriginalType v2, <BR>        FUNC_TYPE func)<BR>    {<BR>    }<BR>    </SPAN><SPAN style="COLOR: #0000ff">void</SPAN><SPAN style="COLOR: #000000"> async_call (<BR>        typename TypeAt </SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #000000">T, </SPAN><SPAN style="COLOR: #000000">0</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000">::Result::OriginalType v0,<BR>        typename TypeAt </SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #000000">T, </SPAN><SPAN style="COLOR: #000000">1</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000">::Result::OriginalType v1,<BR>        typename TypeAt </SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #000000">T, </SPAN><SPAN style="COLOR: #000000">2</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000">::Result::OriginalType v2)<BR>    {<BR>    }<BR>};<BR><BR>template </SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #0000ff">class</SPAN><SPAN style="COLOR: #000000"> T</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000"><BR></SPAN><SPAN style="COLOR: #0000ff">struct</SPAN><SPAN style="COLOR: #000000"> Base </SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #000000">T, </SPAN><SPAN style="COLOR: #000000">4</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000"><BR>{<BR>    typedef </SPAN><SPAN style="COLOR: #0000ff">void</SPAN><SPAN style="COLOR: #000000">(</SPAN><SPAN style="COLOR: #000000">*</SPAN><SPAN style="COLOR: #000000">FUNC_TYPE)(<BR>        typename TypeAt </SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #000000">T, </SPAN><SPAN style="COLOR: #000000">0</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000">::Result::OriginalType, <BR>        typename TypeAt </SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #000000">T, </SPAN><SPAN style="COLOR: #000000">1</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000">::Result::OriginalType,<BR>        typename TypeAt </SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #000000">T, </SPAN><SPAN style="COLOR: #000000">2</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000">::Result::OriginalType,<BR>        typename TypeAt </SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #000000">T, </SPAN><SPAN style="COLOR: #000000">3</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000">::Result::OriginalType);<BR><BR>    </SPAN><SPAN style="COLOR: #0000ff">void</SPAN><SPAN style="COLOR: #000000"> async_call (<BR>        typename TypeAt </SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #000000">T, </SPAN><SPAN style="COLOR: #000000">0</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000">::Result::OriginalType v0, <BR>        typename TypeAt </SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #000000">T, </SPAN><SPAN style="COLOR: #000000">1</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000">::Result::OriginalType v1, <BR>        typename TypeAt </SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #000000">T, </SPAN><SPAN style="COLOR: #000000">2</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000">::Result::OriginalType v2, <BR>        typename TypeAt </SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #000000">T, </SPAN><SPAN style="COLOR: #000000">3</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000">::Result::OriginalType v3,<BR>        FUNC_TYPE func)<BR>    {<BR>    }<BR>    </SPAN><SPAN style="COLOR: #0000ff">void</SPAN><SPAN style="COLOR: #000000"> async_call (<BR>        typename TypeAt </SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #000000">T, </SPAN><SPAN style="COLOR: #000000">0</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000">::Result::OriginalType v0,<BR>        typename TypeAt </SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #000000">T, </SPAN><SPAN style="COLOR: #000000">1</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000">::Result::OriginalType v1,<BR>        typename TypeAt </SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #000000">T, </SPAN><SPAN style="COLOR: #000000">2</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000">::Result::OriginalType v2,<BR>        typename TypeAt </SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #000000">T, </SPAN><SPAN style="COLOR: #000000">3</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000">::Result::OriginalType v3)<BR>    {<BR>    }<BR>};</SPAN></DIV><BR>q部分有点多Q其实还是比较清晰的。注意这个Base的版本已l不是上面所讲的那个?jin)?BR><BR>函数原Ş推导问题p完了(jin)。上面的代码不一定还能编译,昨天是能~译的,被我修改?jin)一些,Z(jin)解释Q又Ҏ(gu)昨天那样子?img src ="http://www.shnenglu.com/cpunion/aggbug/349.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.shnenglu.com/cpunion/" target="_blank">qiezi</a> 2005-09-20 22:34 <a href="http://www.shnenglu.com/cpunion/archive/2005/09/20/349.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>正式建立asgard目 (因ancients已经被h使用?jin)?j)http://www.shnenglu.com/cpunion/archive/2005/09/20/327.htmlqieziqieziTue, 20 Sep 2005 02:30:00 GMThttp://www.shnenglu.com/cpunion/archive/2005/09/20/327.htmlhttp://www.shnenglu.com/cpunion/comments/327.htmlhttp://www.shnenglu.com/cpunion/archive/2005/09/20/327.html#Feedback16http://www.shnenglu.com/cpunion/comments/commentRss/327.htmlhttp://www.shnenglu.com/cpunion/services/trackbacks/327.html
目命名为ancientsQ字面意思是“远古的Q旧的”,实际上这个主题(sh)是旧的?jin)。原本打命名ؓ(f)C++ RemotingQ不q想?jin)一下,q是换个名字Q免得让Z看就x去跟java, c#的remoting比较?BR>
取这个名字主要是因ؓ(f)喜欢看《星际之门》剧集,里面最喜欢的一个种族就是ancients?BR>
asgard是另一个种族,在ancientsq个名字被h占用?jin)的情况下,只好选它?jin)。它的字面意思是“仙宫”,也是不错的名字,呵呵。asgardq个U族的科技非常发达Q有先进的亚I间旅行技术,先进的光传送技术,w体也比较符合一些报道中外星人的样子?BR>
暂时q没扑ֈ合适的I间来放q个目Q就以压~包的Ş式在q个blog上做吧?BR>
打算先实现动态部分,我给它命名ؓ(f)reflectionQ模仿java的,当然也不?x)做它那么完整。这部分必须先做Q这h便用来测试静(rn)态结构?BR>
然后是静(rn)态结构部分,前面已经写了(jin)2ؕ七八p的描述Q剩余问题(函数原Ş推导问题Q基本已l解决了(jin)?BR>
整个框架在Service以下都是环境无关的,q里的环境指的是协议、通讯{环境。也是_(d)定义一个ServiceQƈ不在一开始就指定它所使用的通讯协议。定义完成以后,把它指定l一个协议,可以实现协议绑定,甚至在运行时d态切换到另一个协议。当然这可能是不合理的,不过我认为如果支持这U做法,本n是灉|性的一U体现?BR>


前面q有些地方,和实际情冉|些差别的Q需要补充完善。简要描q如下:(x)

使用宏来定义ServiceQ前面只定义?jin)方法的原型、名U、服务端l定的函敎ͼ其实q差一个重要的东西Q就是参数的名字?BR>如果使用自己的协议,或者是序存储的协议,比如BENCODEQ来作ؓ(f)q程调用协议Q那么参数的名字是不重要的,只要按顺序把参数序列化、反序列化就可以?jin)?BR>但在使用SOAP作ؓ(f)q程调用协议Ӟ得考虑为参数加上名字了(jin)QSOAP是从XML元素中,按参数名U来提取参数值的Q虽然我们可以ؓ(f)参数生成一个名字,但这个名字不能描q参数所表达的意思?BR>所以需要考虑为参数取上名字?BR>
暂时p充这一点,其它斚w有等q一步研I?img src ="http://www.shnenglu.com/cpunion/aggbug/327.html" width = "1" height = "1" />

qiezi 2005-09-20 10:30 发表评论
]]>
为CQ+实现一个IDL Q一Q?/title><link>http://www.shnenglu.com/cpunion/archive/2005/09/17/284.html</link><dc:creator>qiezi</dc:creator><author>qiezi</author><pubDate>Sat, 17 Sep 2005 11:40:00 GMT</pubDate><guid>http://www.shnenglu.com/cpunion/archive/2005/09/17/284.html</guid><wfw:comment>http://www.shnenglu.com/cpunion/comments/284.html</wfw:comment><comments>http://www.shnenglu.com/cpunion/archive/2005/09/17/284.html#Feedback</comments><slash:comments>4</slash:comments><wfw:commentRss>http://www.shnenglu.com/cpunion/comments/commentRss/284.html</wfw:commentRss><trackback:ping>http://www.shnenglu.com/cpunion/services/trackbacks/284.html</trackback:ping><description><![CDATA[<P>前面单写?jin)点静(rn)态结构,q一ơ将主要x动态模型以?qing)调用方式?/P> <P>q个pd的名字叫“ؓ(f)C++实现一个IDL”,实际上应该叫“ؓ(f)C++实现一个Remoting”可能更好一些,说是IDLQ主要是想通过宏,使用单的cd定义辑ֈ自动生成调用代码的目的?/P> <P><STRONG>一、首先来看看调用?fn)惯?/STRONG></P> <P>从调用习(fn)惯入手,主要是因为看到目前有很多?工具包在调用上都有很多不便之处。假如能在一开始就从这点出发,p把调用接口设计得更好一些?/P> <P>先来看看服务端如何开放一个服务?/P> <DIV style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000"> (tng)main (tng)()<BR>{<BR> (tng) (tng) (tng) (tng)</SPAN><SPAN style="COLOR: #008000">//</SPAN><SPAN style="COLOR: #008000"> (tng)发布为SOAP服务Q先生成一个服务容器?BR> (tng) (tng) (tng) (tng)</SPAN><SPAN style="COLOR: #008000">//</SPAN><SPAN style="COLOR: #008000"> (tng)服务发布在localhost?911上,localhost用来l定loopback|卡?/SPAN><SPAN style="COLOR: #008000"><BR></SPAN><SPAN style="COLOR: #000000"> (tng) (tng) (tng) (tng)SOAPProxy (tng)soap_service (tng)(</SPAN><SPAN style="COLOR: #000000">7911</SPAN><SPAN style="COLOR: #000000">, (tng)“localhost?;<BR><BR> (tng) (tng) (tng) (tng)TestService (tng)test_service; (tng)<BR> (tng) (tng) (tng) (tng)soap_service.addService (tng) (tng)(“test_service? (tng)</SPAN><SPAN style="COLOR: #000000">&</SPAN><SPAN style="COLOR: #000000">test_service);<BR><BR> (tng) (tng) (tng) (tng)TestService (tng)service1;<BR> (tng) (tng) (tng) (tng)soap_service.addService (tng)(“HelloService? (tng)</SPAN><SPAN style="COLOR: #000000">&</SPAN><SPAN style="COLOR: #000000">service1);<BR><BR> (tng) (tng) (tng) (tng)</SPAN><SPAN style="COLOR: #0000ff">try</SPAN><SPAN style="COLOR: #000000">{<BR> (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)soap_service.run (tng)();<BR> (tng) (tng) (tng) (tng)} (tng)</SPAN><SPAN style="COLOR: #0000ff">catch</SPAN><SPAN style="COLOR: #000000"> (tng)(SocketException</SPAN><SPAN style="COLOR: #000000">&</SPAN><SPAN style="COLOR: #000000"> (tng)e)<BR> (tng) (tng) (tng) (tng){<BR> (tng) (tng) (tng) (tng)} (tng)</SPAN><SPAN style="COLOR: #0000ff">catch</SPAN><SPAN style="COLOR: #000000"> (tng)(SignalException</SPAN><SPAN style="COLOR: #000000">&</SPAN><SPAN style="COLOR: #000000"> (tng)e)<BR> (tng) (tng) (tng) (tng){<BR> (tng) (tng) (tng) (tng)}<BR><BR> (tng) (tng) (tng) (tng)</SPAN><SPAN style="COLOR: #0000ff">return</SPAN><SPAN style="COLOR: #000000"> (tng)</SPAN><SPAN style="COLOR: #000000">0</SPAN><SPAN style="COLOR: #000000">;<BR>}</SPAN></DIV> <P><BR>我希望就是这么简单,客户端调用有多种方式Q?BR>1、?tng)用服务的IDL定义Q直接调用:(x)</P> <DIV style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000"> (tng)main (tng)()<BR>{<BR> (tng) (tng) (tng) (tng)SOAPProxy (tng)soap_service (tng)(</SPAN><SPAN style="COLOR: #000000">7911</SPAN><SPAN style="COLOR: #000000">, (tng)“localhost?;<BR><BR> (tng) (tng) (tng) (tng)</SPAN><SPAN style="COLOR: #0000ff">try</SPAN><SPAN style="COLOR: #000000">{<BR> (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)TestService (tng)test_service (tng)(“test_service? (tng)</SPAN><SPAN style="COLOR: #000000">&</SPAN><SPAN style="COLOR: #000000">soap_service);<BR> (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)test_service.method1 (tng)(</SPAN><SPAN style="COLOR: #008000">/*</SPAN><SPAN style="COLOR: #008000"><IMG src="http://www.shnenglu.com/images/dot.gif"></SPAN><SPAN style="COLOR: #008000">*/</SPAN><SPAN style="COLOR: #000000">);<BR> (tng) (tng) (tng) (tng)} (tng)</SPAN><SPAN style="COLOR: #0000ff">catch</SPAN><SPAN style="COLOR: #000000"> (tng)(SocketException</SPAN><SPAN style="COLOR: #000000">&</SPAN><SPAN style="COLOR: #000000"> (tng)e)<BR> (tng) (tng) (tng) (tng){<BR> (tng) (tng) (tng) (tng)}<BR> (tng) (tng) (tng) (tng)</SPAN><SPAN style="COLOR: #0000ff">return</SPAN><SPAN style="COLOR: #000000"> (tng)</SPAN><SPAN style="COLOR: #000000">0</SPAN><SPAN style="COLOR: #000000">;<BR>}</SPAN></DIV> <P><BR>q种方式比较单,调用时会(x)(g)查是否已l连接,然后发送调用请求,q处理调用结果?/P> <P>2、?tng)服务验证方式?x)</P> <DIV style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000"> (tng)main (tng)()<BR>{<BR> (tng) (tng) (tng) (tng)SOAPProxy (tng)soap_service (tng)(</SPAN><SPAN style="COLOR: #000000">7911</SPAN><SPAN style="COLOR: #000000">, (tng)“localhost?;<BR> (tng) (tng) (tng) (tng)TestService (tng)test_service;<BR> (tng) (tng) (tng) (tng)soap_service.getService (tng)(“test_service? (tng)</SPAN><SPAN style="COLOR: #000000">&</SPAN><SPAN style="COLOR: #000000">test_service);<BR><BR> (tng) (tng) (tng) (tng)</SPAN><SPAN style="COLOR: #0000ff">if</SPAN><SPAN style="COLOR: #000000"> (tng)(test_service)<BR> (tng) (tng) (tng) (tng){<BR> (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)</SPAN><SPAN style="COLOR: #0000ff">try</SPAN><SPAN style="COLOR: #000000">{<BR> (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)test_service.method1 (tng)(</SPAN><SPAN style="COLOR: #008000">/*</SPAN><SPAN style="COLOR: #008000"><IMG src="http://www.shnenglu.com/images/dot.gif"></SPAN><SPAN style="COLOR: #008000">*/</SPAN><SPAN style="COLOR: #000000">);<BR> (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)} (tng)</SPAN><SPAN style="COLOR: #0000ff">catch</SPAN><SPAN style="COLOR: #000000"> (tng)(SocketException</SPAN><SPAN style="COLOR: #000000">&</SPAN><SPAN style="COLOR: #000000"> (tng)e)<BR> (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng){<BR> (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)}<BR> (tng) (tng) (tng) (tng)}<BR> (tng) (tng) (tng) (tng)</SPAN><SPAN style="COLOR: #0000ff">return</SPAN><SPAN style="COLOR: #000000"> (tng)</SPAN><SPAN style="COLOR: #000000">0</SPAN><SPAN style="COLOR: #000000">;<BR>}</SPAN></DIV> <P><BR>3、?tng)服务发现方式?x)</P> <DIV style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000"> (tng)main (tng)()<BR>{<BR> (tng) (tng) (tng) (tng)SOAPProxy (tng)soap_service (tng)(</SPAN><SPAN style="COLOR: #000000">7911</SPAN><SPAN style="COLOR: #000000">, (tng)“localhost?;<BR> (tng) (tng) (tng) (tng)vector (tng)</SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #0000ff">string</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000"> (tng)services_name (tng)</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000"> (tng)soap_service.getServiceNames (tng)();<BR> (tng) (tng) (tng) (tng)</SPAN><SPAN style="COLOR: #008000">//</SPAN><SPAN style="COLOR: #008000"> (tng)<IMG src="http://www.shnenglu.com/images/dot.gif"></SPAN><SPAN style="COLOR: #008000"><BR></SPAN><SPAN style="COLOR: #000000"> (tng) (tng) (tng) (tng)I(yng)Service</SPAN><SPAN style="COLOR: #000000">*</SPAN><SPAN style="COLOR: #000000"> (tng)test_service (tng)</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000"> (tng)soap_service.getService (tng)(“test_service?;<BR> (tng) (tng) (tng) (tng)</SPAN><SPAN style="COLOR: #0000ff">if</SPAN><SPAN style="COLOR: #000000"> (tng)(test_service)<BR> (tng) (tng) (tng) (tng){<BR> (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)vector (tng)</SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #0000ff">string</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000"> (tng)methods (tng)</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000"> (tng)test_service</SPAN><SPAN style="COLOR: #000000">-></SPAN><SPAN style="COLOR: #000000">getMethodNames (tng)();<BR> (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)I(yng)Method</SPAN><SPAN style="COLOR: #000000">*</SPAN><SPAN style="COLOR: #000000"> (tng)method (tng)</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000"> (tng)test_service</SPAN><SPAN style="COLOR: #000000">-></SPAN><SPAN style="COLOR: #000000">getMethod (tng)(“method1?;<BR> (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)vector (tng)</SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #000000">Type</SPAN><SPAN style="COLOR: #000000">*></SPAN><SPAN style="COLOR: #000000"> (tng)types (tng)</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000"> (tng)method</SPAN><SPAN style="COLOR: #000000">-></SPAN><SPAN style="COLOR: #000000">getParameterType (tng)s()<BR> (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)method</SPAN><SPAN style="COLOR: #000000">-></SPAN><SPAN style="COLOR: #000000">addArg (tng)(</SPAN><SPAN style="COLOR: #000000">3</SPAN><SPAN style="COLOR: #000000">);<BR> (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)method</SPAN><SPAN style="COLOR: #000000">-></SPAN><SPAN style="COLOR: #000000">addArg (tng)(</SPAN><SPAN style="COLOR: #000000">4</SPAN><SPAN style="COLOR: #000000">);<BR> (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)</SPAN><SPAN style="COLOR: #008000">//</SPAN><SPAN style="COLOR: #008000"> (tng)<IMG src="http://www.shnenglu.com/images/dot.gif"></SPAN><SPAN style="COLOR: #008000"><BR></SPAN><SPAN style="COLOR: #000000"> (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)method</SPAN><SPAN style="COLOR: #000000">-></SPAN><SPAN style="COLOR: #000000">invoke (tng)();<BR> (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)</SPAN><SPAN style="COLOR: #008000">//</SPAN><SPAN style="COLOR: #008000"> (tng)<IMG src="http://www.shnenglu.com/images/dot.gif"></SPAN><SPAN style="COLOR: #008000"><BR></SPAN><SPAN style="COLOR: #000000"> (tng) (tng) (tng) (tng)}<BR> (tng) (tng) (tng) (tng)</SPAN><SPAN style="COLOR: #0000ff">return</SPAN><SPAN style="COLOR: #000000"> (tng)</SPAN><SPAN style="COLOR: #000000">0</SPAN><SPAN style="COLOR: #000000">;<BR>}</SPAN></DIV> <P><STRONG><BR>二、基本需求?BR><BR></STRONG>单分析一下,上面一共涉?qing)?jin)哪些cdQ?BR>IProxy:<BR>q是所有Proxycȝ基类(和接?Q它可以容纳多个服务对象Q提供服务绑定、服务查询、服务发现、服务验证?BR>IService:<BR>所有Servicecȝ基类Q可以容U_个方?Method)Q提供方法查询、服务验证?BR>IMethod:<BR>所有Method模板cȝ基类Q容U_个参敎ͼ包括q回|可通过查询参数cd获得Ҏ(gu)的类型定义?BR>IParameter:<BR>所有参数的基类Q包含一个参数类型描q和一个参数倹{?BR>IType:<BR>所有类型的基类Q预定义?jin)一些基本类型,可自定义cd?/P> <P>看v来挺多的Q其实很难接触到q些Q只需要用宏来定义一个服务,可以通过模板的类型推|自动生成q些复杂的定义?/P><STRONG>三、调用过E?BR><BR></STRONG>以下只简单分析一下同步调用,异步调用是以后的扩充话题?BR>Ҏ(gu)W二节的3U不同调用过E,要描q如下:(x) <OL> <LI>直接调用?BR><BR> <UL> <LI>生成SOAPProxyQ让它连接到q程L?BR> <LI>生成一个TestService对象Q设|远E主Z的服务名Uͼq指定用SOAPProxyQ也即用SOAP协议?BR> <LI>调用TestService::method1Ҏ(gu)。根据method1的定义,把服务名U、方法名U、各个in参数{打包成一个“集合”,交给SOAPProxy处理?BR> <LI>SOAPProxy把这个“集合”{换成SOAP消息Q发送到q程LQ阻塞线E?BR> <LI>q程L上的SOAPProxy对象收到数据Q进行解析。当解析Z个服务调用时Q把它交lTestService服务处理?BR> <LI>TestService解析Z个方法调用,把它交给Method处理?BR> <LI>Method解析出各个参敎ͼ验证参数cd、完整性等Qƈ执行调用或返回错误?BR> <LI>Method调用的返回信?包括调用l果、返回倹{out参数{?被打包成一个“集合”,交给TestService处理?BR> <LI>TestService处理后,交给SOAPProxy?BR> <LI>SOAPProxy把结果打包成SOAP消息Q发回调用端?BR> <LI>调用端解析SOAP消息Q把OUT参数Dl调用者提供的对象Q调用完成?</LI></UL> <P> (tng)</P> <LI>服务验证方式?BR> <UL> <LI>生成SOAPProxyQ让它连接到q程L?BR> <LI>生成TestService对象Q调用SOAPProxy的getService验证版本?BR> <LI>SOAPProxy把TestService对象的信?名称、成员及(qing)基类型等)发送到q程LQ阻塞?BR> <LI>q程L解析收到的信息,查找服务名,q比较查扑ֈ的服务类型与解析得到的类型?BR> <LI>比较l果发回l调用端?BR> <LI>调用端接着采用直接调用的方式,调用q程服务?/LI></UL><BR>q种方式看v来多?jin)一些操作,不过验证的好处是能够减少调用时的异常? <P></P> <LI>服务发现方式?BR> <UL> <LI>生成SOAPProxyQ让它连接到q程L?BR> <LI>查询q程开攄服务名称?可省?<BR> <LI>查找特定服务Q得到服务描qC息?BR> <LI>查找服务中的Ҏ(gu)Q得到方法描qC息?BR> <LI>压入各个参数Qƈ执行调用?BR> <LI>调用前先判断参数是否与描qC_(d)然后调用SOAPProxy生成SOAP消息Q发送到q程LQ阻塞?BR> <LI>q程L解析?gu)用。。。后面过E与W?U方式相同,q程Lq不知道客户端用的是哪U方式来调用。远E主机处理结束,返回SOAP消息l调用端?BR> <LI>调用端解析出调用l果Qƈ把各个OUT参数的Dlmethod对象?/LI></UL><BR>使用q种方式Q调用端不需要服务的cd定义? <P></P></LI></OL> <P><STRONG>四、异步调?异步分派(AMI/AMD)?BR></STRONG><BR>同步调用Ӟ调用端线E需要等待调用结果,服务端线E也要等待调用结束返回,才处理下一个调用?BR>Z(jin)在服务调用期间让U程能做更多的事Q?BR>调用端把调用交给U程池完成,q在调用完成后采用某U机刉知U程处理l果Q或者直接由U程池中的调用线E调用结果处理函数。这U方式称为AMI(异步Ҏ(gu)调用)?BR>服务端主U程则把接收到的消息解析后,攑օ处理队列Q由U程池去处理调用q程。当调用完成后,l果攑օl果队列Q由ȝE处理成消息Q发送回调用端。这U方式称为AMD(异步Ҏ(gu)分派)?BR>调用端和服务端依旧是使用通讯协议来沟通,双方都不知道Ҏ(gu)是否采用?jin)异步方式?/P> <P>AMI和AMD对于?rn)态定义的服务是有影响的,比如下面一个服务:(x)</P> <DIV style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><SPAN style="COLOR: #0000ff">struct</SPAN><SPAN style="COLOR: #000000"> (tng)TestService<BR>{<BR> (tng) (tng) (tng) (tng)Method (tng)</SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #0000ff">void</SPAN><SPAN style="COLOR: #000000">(</SPAN><SPAN style="COLOR: #0000ff">in</SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000">, (tng)</SPAN><SPAN style="COLOR: #0000ff">out</SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000">)</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000"> (tng)method1;<BR>}</SPAN></DIV> <P><BR>在同步调用时Q它的调用方式:(x)</P> <DIV style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><SPAN style="COLOR: #000000">TestService (tng)test_service;<BR></SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000"> (tng)a;<BR>service.method1 (tng)(</SPAN><SPAN style="COLOR: #000000">3</SPAN><SPAN style="COLOR: #000000">, (tng)a); (tng)</SPAN><SPAN style="COLOR: #008000">//</SPAN><SPAN style="COLOR: #008000"> (tng)或者?tng)service.method1 (tng)(3, (tng)&a)Q打兼容这2U方式?/SPAN></DIV> <P><BR>异步调用Ӟ调用方式Q?/P> <DIV style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><SPAN style="COLOR: #0000ff">void</SPAN><SPAN style="COLOR: #000000"> (tng)method1_result (tng)(</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">, (tng)</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">);<BR>TestService (tng)test_service;<BR>test_service.method1.async_call(</SPAN><SPAN style="COLOR: #000000">3</SPAN><SPAN style="COLOR: #000000">, (tng)method1_result); (tng)</SPAN><SPAN style="COLOR: #008000">//</SPAN><SPAN style="COLOR: #008000"> (tng)调用完成后,让调用线E去调用method1_result通知调用l果?BR></SPAN><SPAN style="COLOR: #008000">//</SPAN><SPAN style="COLOR: #008000"> (tng)或者像下面</SPAN><SPAN style="COLOR: #008000"><BR></SPAN><SPAN style="COLOR: #000000">IMethod</SPAN><SPAN style="COLOR: #000000">*</SPAN><SPAN style="COLOR: #000000"> (tng)result (tng)</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000"> (tng)test_service.method1.async_call (tng)(</SPAN><SPAN style="COLOR: #000000">3</SPAN><SPAN style="COLOR: #000000">);<BR></SPAN><SPAN style="COLOR: #0000ff">while</SPAN><SPAN style="COLOR: #000000"> (tng)(</SPAN><SPAN style="COLOR: #000000">!</SPAN><SPAN style="COLOR: #000000">result</SPAN><SPAN style="COLOR: #000000">-></SPAN><SPAN style="COLOR: #000000">done()) (tng) (tng)</SPAN><SPAN style="COLOR: #008000">//</SPAN><SPAN style="COLOR: #008000"> (tng)q有很多好办法,q里只是Z(jin)单?/SPAN><SPAN style="COLOR: #008000"><BR></SPAN><SPAN style="COLOR: #000000">{<BR> (tng) (tng) (tng) (tng)sleep (tng)(</SPAN><SPAN style="COLOR: #000000">1</SPAN><SPAN style="COLOR: #000000">);<BR>}<BR>cout (tng)</SPAN><SPAN style="COLOR: #000000"><<</SPAN><SPAN style="COLOR: #000000"> (tng)result</SPAN><SPAN style="COLOR: #000000">-></SPAN><SPAN style="COLOR: #000000">getArg(</SPAN><SPAN style="COLOR: #000000">1</SPAN><SPAN style="COLOR: #000000">)</SPAN><SPAN style="COLOR: #000000">-></SPAN><SPAN style="COLOR: #000000">toInt(); (tng)<BR></SPAN></DIV> <P><BR>正如上面演示的一P异步调用的结果有2U方式去处理?BR>一是由U程池调用完以后Q接着调用一个函C通知l果。它不需要轮询,不过涉及(qing)C(jin)U程问题Q增加了(jin)一些复杂性?BR>另一U方式调用结束后Q原调用U程在某个适当的“时机”去查询调用l果。这个时机可以是定时查询Q也可以是被U程消息通知而去处理?/P> <P><STRONG>五、其它?BR></STRONG><BR>q一加上前一,应该是提C(jin)全部的要炏V?BR>目前剩下的唯一一个难点,可能是在处理异步调用ӞMethod的定义?BR>正如上面演示的,一个方法在同步调用和异步调用时Q就?U调用方式:(x)</P> <DIV style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><SPAN style="COLOR: #000000">service.method1 (tng)(</SPAN><SPAN style="COLOR: #000000">3</SPAN><SPAN style="COLOR: #000000">, (tng)a);<BR>test_service.method1.async_call(</SPAN><SPAN style="COLOR: #000000">3</SPAN><SPAN style="COLOR: #000000">, (tng)method1_result);<BR>IMethod</SPAN><SPAN style="COLOR: #000000">*</SPAN><SPAN style="COLOR: #000000"> (tng)result (tng)</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000"> (tng)test_service.method1.async_call (tng)(</SPAN><SPAN style="COLOR: #000000">3</SPAN><SPAN style="COLOR: #000000">);</SPAN></DIV> <P><BR>特别圎ͼ它如何根据in和个数和out的个敎ͼ产生?个参C数匹配的异步调用函数Q?BR>再来回顾一下method1的定义:(x)</P> <DIV style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><SPAN style="COLOR: #000000">Method (tng)</SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #0000ff">void</SPAN><SPAN style="COLOR: #000000">(</SPAN><SPAN style="COLOR: #0000ff">in</SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000">, (tng)</SPAN><SPAN style="COLOR: #0000ff">out</SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000">)</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000"> (tng)method1;</SPAN></DIV> <P><BR>昄有一定的复杂性,不过我认是可以处理掉的。拿3个参数的偏特化版本来说明Q?/P> <DIV style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><SPAN style="COLOR: #000000">template (tng)</SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #0000ff">class</SPAN><SPAN style="COLOR: #000000"> (tng)Ret, (tng)</SPAN><SPAN style="COLOR: #0000ff">class</SPAN><SPAN style="COLOR: #000000"> (tng)A, (tng)</SPAN><SPAN style="COLOR: #0000ff">class</SPAN><SPAN style="COLOR: #000000"> (tng)B, (tng)</SPAN><SPAN style="COLOR: #0000ff">class</SPAN><SPAN style="COLOR: #000000"> (tng)C</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000"><BR></SPAN><SPAN style="COLOR: #0000ff">class</SPAN><SPAN style="COLOR: #000000"> (tng)Method (tng)</SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #000000">Out</SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #000000">Ret</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000">(A,B,C)</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000"> (tng): (tng)</SPAN><SPAN style="COLOR: #0000ff">public</SPAN><SPAN style="COLOR: #000000"> (tng)MethodBase (tng)</SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #000000">Out</SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #000000">Ret</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000">,A,B,C</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000"><BR>{<BR>};<BR><BR>template (tng)</SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #0000ff">class</SPAN><SPAN style="COLOR: #000000"> (tng)Ret</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">NullType, (tng)</SPAN><SPAN style="COLOR: #0000ff">class</SPAN><SPAN style="COLOR: #000000"> (tng)A</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">NullType, (tng)</SPAN><SPAN style="COLOR: #0000ff">class</SPAN><SPAN style="COLOR: #000000"> (tng)B</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">NullType, (tng)</SPAN><SPAN style="COLOR: #0000ff">class</SPAN><SPAN style="COLOR: #000000"> (tng)C</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">NullType, (tng)</SPAN><SPAN style="COLOR: #0000ff">class</SPAN><SPAN style="COLOR: #000000"> (tng)D</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">NullType, (tng)I(yng)N_COUNT</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">InCount</SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #000000"> (tng)A,B,C,D</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000">::value (tng)</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000"><BR></SPAN><SPAN style="COLOR: #0000ff">class</SPAN><SPAN style="COLOR: #000000"> (tng)MethodBase<BR>{<BR>};<BR><BR></SPAN></DIV> <P><BR>通过对MethodBasecȝINQCOUNT参数定义偏特化,卛_定义?gu)些不同的版本?BR><BR>当然仅仅是知道了(jin)IN参数的个敎ͼq没有提取出IN参数的类型,所以还?sh)能生成函数的原型,或许需要把typelist加进来了(jin)Qloki中的那个Q?BR><BR><BR><BR>q是后面要考虑的内容,今天先想到这?/P><img src ="http://www.shnenglu.com/cpunion/aggbug/284.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.shnenglu.com/cpunion/" target="_blank">qiezi</a> 2005-09-17 19:40 <a href="http://www.shnenglu.com/cpunion/archive/2005/09/17/284.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>为CQ+实现一个IDL Q零Q?/title><link>http://www.shnenglu.com/cpunion/archive/2005/09/15/272.html</link><dc:creator>qiezi</dc:creator><author>qiezi</author><pubDate>Wed, 14 Sep 2005 17:27:00 GMT</pubDate><guid>http://www.shnenglu.com/cpunion/archive/2005/09/15/272.html</guid><wfw:comment>http://www.shnenglu.com/cpunion/comments/272.html</wfw:comment><comments>http://www.shnenglu.com/cpunion/archive/2005/09/15/272.html#Feedback</comments><slash:comments>4</slash:comments><wfw:commentRss>http://www.shnenglu.com/cpunion/comments/commentRss/272.html</wfw:commentRss><trackback:ping>http://www.shnenglu.com/cpunion/services/trackbacks/272.html</trackback:ping><description><![CDATA[<P>一、问题?BR><BR>q段旉考虑实现一个纯CQ+的分布式服务包装库,要描q如下:(x)</P> <P>有如下类和函敎ͼ(x)</P> <DIV style="BORDER-RIGHT: windowtext 0.5pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: windowtext 0.5pt solid; PADDING-LEFT: 5.4pt; BACKGROUND: #e6e6e6; PADDING-BOTTOM: 4px; BORDER-LEFT: windowtext 0.5pt solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: windowtext 0.5pt solid"> <DIV><SPAN style="COLOR: #0000ff">struct</SPAN><SPAN style="COLOR: #000000"> (tng)Test<BR>{<BR> (tng) (tng) (tng) (tng)</SPAN><SPAN style="COLOR: #0000ff">void</SPAN><SPAN style="COLOR: #000000"> (tng)test1 (tng)(</SPAN><SPAN style="COLOR: #008000">/*</SPAN><SPAN style="COLOR: #008000">in</SPAN><SPAN style="COLOR: #008000">*/</SPAN><SPAN style="COLOR: #000000"> (tng)</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000"> (tng)v1, (tng)</SPAN><SPAN style="COLOR: #008000">/*</SPAN><SPAN style="COLOR: #008000">in</SPAN><SPAN style="COLOR: #008000">*/</SPAN><SPAN style="COLOR: #000000"> (tng)</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">*</SPAN><SPAN style="COLOR: #000000"> (tng)v2);<BR> (tng) (tng) (tng) (tng)</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000"> (tng)test2 (tng)(</SPAN><SPAN style="COLOR: #008000">/*</SPAN><SPAN style="COLOR: #008000">in</SPAN><SPAN style="COLOR: #008000">*/</SPAN><SPAN style="COLOR: #000000"> (tng)</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">&</SPAN><SPAN style="COLOR: #000000"> (tng)v1, (tng)</SPAN><SPAN style="COLOR: #008000">/*</SPAN><SPAN style="COLOR: #008000">out</SPAN><SPAN style="COLOR: #008000">*/</SPAN><SPAN style="COLOR: #000000"> (tng)</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">*</SPAN><SPAN style="COLOR: #000000"> (tng)v2);<BR>};<BR><BR></SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000"> (tng)test_func (tng)(</SPAN><SPAN style="COLOR: #008000">/*</SPAN><SPAN style="COLOR: #008000">in</SPAN><SPAN style="COLOR: #008000">*/</SPAN><SPAN style="COLOR: #000000"> (tng)</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">*</SPAN><SPAN style="COLOR: #000000"> (tng)v1, (tng)</SPAN><SPAN style="COLOR: #008000">/*</SPAN><SPAN style="COLOR: #008000">inout</SPAN><SPAN style="COLOR: #008000">*/</SPAN><SPAN style="COLOR: #000000"> (tng)</SPAN><SPAN style="COLOR: #0000ff">string</SPAN><SPAN style="COLOR: #000000">*</SPAN><SPAN style="COLOR: #000000"> (tng)v2);</SPAN></DIV></DIV> <P><BR>x它们作ؓ(f)服务发布出去Q以SOAP或其它方式。发布ؓ(f)一个TestServiceQƈ让它携带多一些信?</P> <DIV style="BORDER-RIGHT: windowtext 0.5pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: windowtext 0.5pt solid; PADDING-LEFT: 5.4pt; BACKGROUND: #e6e6e6; PADDING-BOTTOM: 4px; BORDER-LEFT: windowtext 0.5pt solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: windowtext 0.5pt solid"> <DIV><SPAN style="COLOR: #0000ff">struct</SPAN><SPAN style="COLOR: #000000"> (tng)TestService<BR>{<BR> (tng) (tng) (tng) (tng)</SPAN><SPAN style="COLOR: #0000ff">void</SPAN><SPAN style="COLOR: #000000"> (tng)test1 (tng)(</SPAN><SPAN style="COLOR: #0000ff">in</SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000"> (tng)v1, (tng)</SPAN><SPAN style="COLOR: #0000ff">in</SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000"> (tng)v2);<BR> (tng) (tng) (tng) (tng)</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000"> (tng)test2 (tng)(</SPAN><SPAN style="COLOR: #0000ff">in</SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000"> (tng)v1, (tng)</SPAN><SPAN style="COLOR: #0000ff">out</SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000"> (tng)v2);<BR> (tng) (tng) (tng) (tng)</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000"> (tng)test_func (tng)(</SPAN><SPAN style="COLOR: #0000ff">in</SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000"> (tng)v1, (tng)inout</SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #0000ff">string</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000"> (tng)v2);<BR>};</SPAN></DIV></DIV> <P><BR>CQ+有许多工兗库来做到这点,但是Q都需要生成一堆代码,很是不爽?BR><BR>其它语言Q比如python, java, c#{,都可以通过自省机制Q抛开IDL在语a内实现?BR><BR>CQ+q不能做这个,它只是缺够的cd信息。比如上面的例子Q如果要发布为服务,那么臛_应该把它的参数、返回值搞得明些Q否则要么会(x)造成不必要的参数传递,要么?x)生错误(把OUT参数取值可不是安全的)(j)?BR><BR>比如上面出现的int, int&, int*Q在作ؓ(f)in参数Ӟ我们是想传递它的|cd为int。而int*和string*作ؓ(f)out参数Ӟ我们惌它传递指针或引用Q当调用q回Ӟ我们l它赋倹{?BR><BR>CQ+语言的类型极Z富,却没有描qC个参数到底是inq是out。java也没有,但它可以正常序列化一个null|在CQ+中,q可能存在一些麻?ch)?BR><BR>再考虑一下char*cdQ假如它是in参数Q那么它是要传递一个字W还是一个字W串QCQ+语言没有对它q行描述?BR><BR>所以要实现一个分布式服务包装Q或代理Q库Q必让发布者提供这些信息?BR><BR>我们知道Q要查询一个远E服务,必须查询相应L端口Q获取服务信息。最单的服务信息包括Q服务列表,每个服务中的Ҏ(gu)列表Q方法的cdQ包括参数和q回值类型,in/out信息{)(j)?BR><BR>实际上,我们是要为CQ+增加一些简单的自省能力。上面那个服务发布接口,实际上离q个要求q有很远Q再来看一下:(x)</P> <DIV style="BORDER-RIGHT: windowtext 0.5pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: windowtext 0.5pt solid; PADDING-LEFT: 5.4pt; BACKGROUND: #e6e6e6; PADDING-BOTTOM: 4px; BORDER-LEFT: windowtext 0.5pt solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: windowtext 0.5pt solid"> <DIV><SPAN style="COLOR: #0000ff">struct</SPAN><SPAN style="COLOR: #000000"> (tng)TestService<BR>{<BR> (tng) (tng) (tng) (tng)</SPAN><SPAN style="COLOR: #0000ff">void</SPAN><SPAN style="COLOR: #000000"> (tng)test1 (tng)(</SPAN><SPAN style="COLOR: #0000ff">in</SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000"> (tng)v1, (tng)</SPAN><SPAN style="COLOR: #0000ff">in</SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000"> (tng)v2);<BR> (tng) (tng) (tng) (tng)</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000"> (tng)test2 (tng)(</SPAN><SPAN style="COLOR: #0000ff">in</SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000"> (tng)v1, (tng)</SPAN><SPAN style="COLOR: #0000ff">out</SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000"> (tng)v2);<BR> (tng) (tng) (tng) (tng)</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000"> (tng)test_func (tng)(</SPAN><SPAN style="COLOR: #0000ff">in</SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000"> (tng)v1, (tng)inout</SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #0000ff">string</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000"> (tng)v2);<BR>};</SPAN></DIV></DIV> <P><BR>可以惌Q它是没有一点自省能力的Q我们如何向它查询,它的名字Q它的方法列表?Ҏ(gu)的类型?它如何与Testcȝ成员函数以及(qing)test_func函数兌Q?/P> <P>二、方向?BR><BR>要让上面那个服务h自省能力Q要做的扩充其实q不多。考虑下面的代码:(x)</P> <DIV style="BORDER-RIGHT: windowtext 0.5pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: windowtext 0.5pt solid; PADDING-LEFT: 5.4pt; BACKGROUND: #e6e6e6; PADDING-BOTTOM: 4px; BORDER-LEFT: windowtext 0.5pt solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: windowtext 0.5pt solid"> <DIV><SPAN style="COLOR: #0000ff">struct</SPAN><SPAN style="COLOR: #000000"> (tng)TestService (tng): (tng)</SPAN><SPAN style="COLOR: #0000ff">public</SPAN><SPAN style="COLOR: #000000"> (tng)Service<BR>{<BR> (tng) (tng) (tng) (tng)TestService (tng)();<BR> (tng) (tng) (tng) (tng)Method (tng)</SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #0000ff">void</SPAN><SPAN style="COLOR: #000000">(</SPAN><SPAN style="COLOR: #0000ff">in</SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000">, (tng)</SPAN><SPAN style="COLOR: #0000ff">in</SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000">)</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000"> (tng)test1;<BR> (tng) (tng) (tng) (tng)Method (tng)</SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">(</SPAN><SPAN style="COLOR: #0000ff">in</SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000">, (tng)</SPAN><SPAN style="COLOR: #0000ff">out</SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000">)</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000"> (tng)test2;<BR> (tng) (tng) (tng) (tng)Method (tng)</SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">(</SPAN><SPAN style="COLOR: #0000ff">in</SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000">, (tng)inout</SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #0000ff">string</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000">) (tng)test_func;<BR>};</SPAN></DIV></DIV> <P><BR>q几个Method可以用自己写的委托类来做?BR><BR>1、假如我们在TestService的构造函数里l它分配一个“TestService”名字,q且ServicecdC(jin)查询名字的接口,那么它就知道它自q名字?jin)?BR><BR>2、假如在TestService的构造函数里为各个Method分配名字Qƈ且注册到TestServiceQ那么它?yu)p够查询方法列表?BR><BR>3、方法的cdQ通过模板方式Q把各个参数cd攉hQ给个字W串名称可以了(jin)?BR><BR>使用宏来实现Q大概可以写成这P(x)<BR><BR></P> <P></P> <DIV style="BORDER-RIGHT: windowtext 0.5pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: windowtext 0.5pt solid; PADDING-LEFT: 5.4pt; BACKGROUND: #e6e6e6; PADDING-BOTTOM: 4px; BORDER-LEFT: windowtext 0.5pt solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: windowtext 0.5pt solid"> <DIV><SPAN style="COLOR: #000000">BEGIN_SERVICE (tng)(TestService)<BR> (tng) (tng) (tng) (tng)METHOD (tng)(</SPAN><SPAN style="COLOR: #0000ff">void</SPAN><SPAN style="COLOR: #000000">(</SPAN><SPAN style="COLOR: #0000ff">in</SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000">, (tng)</SPAN><SPAN style="COLOR: #0000ff">in</SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000">), (tng)test1, (tng)</SPAN><SPAN style="COLOR: #000000">&</SPAN><SPAN style="COLOR: #000000">Test::test1)<BR> (tng) (tng) (tng) (tng)METHOD (tng)(</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">(</SPAN><SPAN style="COLOR: #0000ff">in</SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000">, (tng)</SPAN><SPAN style="COLOR: #0000ff">out</SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000">), (tng)test2, (tng)</SPAN><SPAN style="COLOR: #000000">&</SPAN><SPAN style="COLOR: #000000">Test::test2)<BR> (tng) (tng) (tng) (tng)METHOD (tng)(</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #0000ff">in</SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000">, (tng)inout</SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #0000ff">string</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000">), (tng)test_func, (tng)test_func)<BR>END_SERVICE (tng)()</SPAN></DIV></DIV> <P><BR>通过上面q几个宏Q我们能够生成TestService声明?BR><BR>不过Q有几个问题Q罗列如下,q一一解决它:(x)<BR><BR>1、如何把函数指针传给它?如何把方法名UCl它Q?BR>q个只是CQ+语言为我们增加了(jin)一些麻?ch),我们无法在定义成员的地方调用它的构造函敎ͼ不过qƈ不会(x)造成多大障碍?BR>上面的METHOD宏如果只是生成类的声明,那么函数指针可以省略。我把它加上的原因是Q它可以被我用Ctrl+C, Ctrl+Vq种世界上最先进的技术原h贝下来,q且通过单修改的Ҏ(gu)实现q种世界上最先进的重用?BR><BR>上面的代码经q修改,l果成q样Q?/P> <DIV style="BORDER-RIGHT: windowtext 0.5pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: windowtext 0.5pt solid; PADDING-LEFT: 5.4pt; BACKGROUND: #e6e6e6; PADDING-BOTTOM: 4px; BORDER-LEFT: windowtext 0.5pt solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: windowtext 0.5pt solid"> <DIV><SPAN style="COLOR: #000000">BEGIN_SERVICE (tng)(TestService)<BR> (tng) (tng) (tng) (tng)METHOD (tng)(</SPAN><SPAN style="COLOR: #0000ff">void</SPAN><SPAN style="COLOR: #000000">(</SPAN><SPAN style="COLOR: #0000ff">in</SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000">, (tng)</SPAN><SPAN style="COLOR: #0000ff">in</SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000">), (tng)test1, (tng)</SPAN><SPAN style="COLOR: #000000">&</SPAN><SPAN style="COLOR: #000000">Test::test1)<BR> (tng) (tng) (tng) (tng)METHOD (tng)(</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">(</SPAN><SPAN style="COLOR: #0000ff">in</SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000">, (tng)</SPAN><SPAN style="COLOR: #0000ff">out</SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000">), (tng)test2, (tng)</SPAN><SPAN style="COLOR: #000000">&</SPAN><SPAN style="COLOR: #000000">Test::test2)<BR> (tng) (tng) (tng) (tng)METHOD (tng)(</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #0000ff">in</SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000">, (tng)inout</SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #0000ff">string</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000">), (tng)test_func, (tng)test_func)<BR><BR> (tng) (tng) (tng) (tng)BEGIN_DEFINE (tng)(TestService)<BR> (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)METHOD_DEFINE (tng)(</SPAN><SPAN style="COLOR: #0000ff">void</SPAN><SPAN style="COLOR: #000000">(</SPAN><SPAN style="COLOR: #0000ff">in</SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000">, (tng)</SPAN><SPAN style="COLOR: #0000ff">in</SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000">), (tng)test1, (tng)</SPAN><SPAN style="COLOR: #000000">&</SPAN><SPAN style="COLOR: #000000">Test::test1)<BR> (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)METHOD_DEFINE(</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">(</SPAN><SPAN style="COLOR: #0000ff">in</SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000">, (tng)</SPAN><SPAN style="COLOR: #0000ff">out</SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000">), (tng)test2, (tng)</SPAN><SPAN style="COLOR: #000000">&</SPAN><SPAN style="COLOR: #000000">Test::test2)<BR> (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)METHOD_DEFINE(</SPAN><SPAN style="COLOR: #0000ff">int(</SPAN><SPAN style="COLOR: #0000ff">in</SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000">, (tng)inout</SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #0000ff">string</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000">), (tng)test_func, (tng)test_func)<BR> (tng) (tng) (tng) (tng)END_DEFINE (tng)()<BR><BR>END_SERVICE (tng)()</SPAN></DIV></DIV> <P><BR>看上d应得非常整齐Q修改v来也比较单。上面那部分被扩充ؓ(f)如下代码Q?/P> <DIV style="BORDER-RIGHT: windowtext 0.5pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: windowtext 0.5pt solid; PADDING-LEFT: 5.4pt; BACKGROUND: #e6e6e6; PADDING-BOTTOM: 4px; BORDER-LEFT: windowtext 0.5pt solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: windowtext 0.5pt solid"> <DIV><SPAN style="COLOR: #0000ff">struct</SPAN><SPAN style="COLOR: #000000"> (tng)TestService (tng): (tng)</SPAN><SPAN style="COLOR: #0000ff">public</SPAN><SPAN style="COLOR: #000000"> (tng)Service<BR>{<BR> (tng) (tng) (tng) (tng)Method (tng)</SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #0000ff">void</SPAN><SPAN style="COLOR: #000000">(</SPAN><SPAN style="COLOR: #0000ff">in</SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000">, (tng)</SPAN><SPAN style="COLOR: #0000ff">in</SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000">)</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000"> (tng)test1;<BR> (tng) (tng) (tng) (tng)Method (tng)</SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">(</SPAN><SPAN style="COLOR: #0000ff">in</SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000">, (tng)</SPAN><SPAN style="COLOR: #0000ff">out</SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000">)</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000"> (tng)test2;<BR> (tng) (tng) (tng) (tng)Method (tng)</SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">(</SPAN><SPAN style="COLOR: #0000ff">in</SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000">, (tng)inout</SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #0000ff">string</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000">) (tng)test_func;<BR> (tng) (tng) (tng) (tng)TestService (tng)()<BR> (tng) (tng) (tng) (tng): (tng)Service (tng)(</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">TestService</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">)<BR> (tng) (tng) (tng) (tng){<BR> (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)test1.setName (tng)(</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">test1</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">);<BR> (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)test1.setMethod (tng)(</SPAN><SPAN style="COLOR: #000000">&</SPAN><SPAN style="COLOR: #000000">Test::test1);<BR> (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)</SPAN><SPAN style="COLOR: #0000ff">this</SPAN><SPAN style="COLOR: #000000">-></SPAN><SPAN style="COLOR: #000000">registerMethod (tng)(</SPAN><SPAN style="COLOR: #000000">&</SPAN><SPAN style="COLOR: #000000">test1);<BR> (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)test2.setName (tng)(</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">test2</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">);<BR> (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)test2.setMethod (tng)(</SPAN><SPAN style="COLOR: #000000">&</SPAN><SPAN style="COLOR: #000000">Test::test2);<BR> (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)</SPAN><SPAN style="COLOR: #0000ff">this</SPAN><SPAN style="COLOR: #000000">-></SPAN><SPAN style="COLOR: #000000">registerMethod (tng)(</SPAN><SPAN style="COLOR: #000000">&</SPAN><SPAN style="COLOR: #000000">test2);<BR> (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)test_func.setName (tng)(</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">test_func</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">);<BR> (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)test_func.setMethod (tng)(test_func);<BR> (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)</SPAN><SPAN style="COLOR: #0000ff">this</SPAN><SPAN style="COLOR: #000000">-></SPAN><SPAN style="COLOR: #000000">registerMethod (tng)(</SPAN><SPAN style="COLOR: #000000">&</SPAN><SPAN style="COLOR: #000000">test3);<BR> (tng) (tng) (tng) (tng)}<BR>};</SPAN></DIV></DIV> <P><BR>基本上需要的东西都在q里?jin)?BR><BR>2、客L(fng)的问题?BR></P> <P>上面q种映射Q直接拿到客L(fng)?x)有问题QTestcdtest_func函数我们q不打算交给客户端,所以用函数指针会(x)出现链接错误?BR><BR>实际上客L(fng)不需要这个,我们惛_法把它拿掉就行了(jin)。客L(fng)实际需要生成的代码如下Q?BR><BR></P> <DIV style="BORDER-RIGHT: windowtext 0.5pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: windowtext 0.5pt solid; PADDING-LEFT: 5.4pt; BACKGROUND: #e6e6e6; PADDING-BOTTOM: 4px; BORDER-LEFT: windowtext 0.5pt solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: windowtext 0.5pt solid"> <DIV><SPAN style="COLOR: #0000ff">struct</SPAN><SPAN style="COLOR: #000000"> (tng)TestService (tng): (tng)</SPAN><SPAN style="COLOR: #0000ff">public</SPAN><SPAN style="COLOR: #000000"> (tng)Service<BR>{<BR> (tng) (tng) (tng) (tng)Method (tng)</SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #0000ff">void</SPAN><SPAN style="COLOR: #000000">(</SPAN><SPAN style="COLOR: #0000ff">in</SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000">, (tng)</SPAN><SPAN style="COLOR: #0000ff">in</SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000">)</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000"> (tng)test1;<BR> (tng) (tng) (tng) (tng)Method (tng)</SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">(</SPAN><SPAN style="COLOR: #0000ff">in</SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000">, (tng)</SPAN><SPAN style="COLOR: #0000ff">out</SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000">)</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000"> (tng)test2;<BR> (tng) (tng) (tng) (tng)Method (tng)</SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">(</SPAN><SPAN style="COLOR: #0000ff">in</SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000">, (tng)inout</SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #0000ff">string</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000">) (tng)test_func;<BR> (tng) (tng) (tng) (tng)TestService (tng)()<BR> (tng) (tng) (tng) (tng): (tng)Service (tng)(</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">TestService</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">)<BR> (tng) (tng) (tng) (tng){<BR> (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)test1.setName (tng)(</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">test1</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">);<BR> (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)</SPAN><SPAN style="COLOR: #0000ff">this</SPAN><SPAN style="COLOR: #000000">-></SPAN><SPAN style="COLOR: #000000">registerMethod (tng)(</SPAN><SPAN style="COLOR: #000000">&</SPAN><SPAN style="COLOR: #000000">test1);<BR> (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)test2.setName (tng)(</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">test2</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">);<BR> (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)</SPAN><SPAN style="COLOR: #0000ff">this</SPAN><SPAN style="COLOR: #000000">-></SPAN><SPAN style="COLOR: #000000">registerMethod (tng)(</SPAN><SPAN style="COLOR: #000000">&</SPAN><SPAN style="COLOR: #000000">test2);<BR> (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)test_func.setName (tng)(</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">test_func</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">);<BR> (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)</SPAN><SPAN style="COLOR: #0000ff">this</SPAN><SPAN style="COLOR: #000000">-></SPAN><SPAN style="COLOR: #000000">registerMethod (tng)(</SPAN><SPAN style="COLOR: #000000">&</SPAN><SPAN style="COLOR: #000000">test3);<BR> (tng) (tng) (tng) (tng)}<BR>};</SPAN></DIV></DIV> <P><BR>q是上面提到的,C++l我们带来的ȝ(ch)。这ơ需要另一l宏来完成它Q?/P> <DIV style="BORDER-RIGHT: windowtext 0.5pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: windowtext 0.5pt solid; PADDING-LEFT: 5.4pt; BACKGROUND: #e6e6e6; PADDING-BOTTOM: 4px; BORDER-LEFT: windowtext 0.5pt solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: windowtext 0.5pt solid"> <DIV><SPAN style="COLOR: #000000">BEGIN_SERVICE_D (tng)(TestService)<BR> (tng) (tng) (tng) (tng)METHOD_D (tng)(</SPAN><SPAN style="COLOR: #0000ff">void</SPAN><SPAN style="COLOR: #000000">(</SPAN><SPAN style="COLOR: #0000ff">in</SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000">, (tng)</SPAN><SPAN style="COLOR: #0000ff">in</SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000">), (tng)test1)<BR> (tng) (tng) (tng) (tng)METHOD_D (tng)(</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">(</SPAN><SPAN style="COLOR: #0000ff">in</SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000">, (tng)</SPAN><SPAN style="COLOR: #0000ff">out</SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000">), (tng)test2)<BR> (tng) (tng) (tng) (tng)METHOD_D (tng)(</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">(</SPAN><SPAN style="COLOR: #0000ff">in</SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000">, (tng)inout</SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #0000ff">string</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000">), (tng)test_func)<BR><BR> (tng) (tng) (tng) (tng)BEGIN_DEFINE_D (tng)(TestService)<BR> (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)METHOD_DEFINE_D (tng)(</SPAN><SPAN style="COLOR: #0000ff">void</SPAN><SPAN style="COLOR: #000000">(</SPAN><SPAN style="COLOR: #0000ff">in</SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000">, (tng)</SPAN><SPAN style="COLOR: #0000ff">in</SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000">), (tng)test1)<BR> (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)METHOD_DEFINE_D(</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">(</SPAN><SPAN style="COLOR: #0000ff">in</SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000">, (tng)</SPAN><SPAN style="COLOR: #0000ff">out</SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000">), (tng)test2)<BR> (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)METHOD_DEFINE_D(</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">(</SPAN><SPAN style="COLOR: #0000ff">in</SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000">, (tng)inout</SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #0000ff">string</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000">), (tng)test_func)<BR> (tng) (tng) (tng) (tng)END_DEFINE_D (tng)()<BR><BR>END_SERVICE_D (tng)()</SPAN></DIV></DIV> <P><BR>METHOD*和METHOD_DEFINE*宏的参数都有一些多余的信息Q没有去掉是因ؓ(f)攑֜一起容易看到写错的地方。(q个技巧来源于前几天看的一BLOGQ很报歉没有C地址Q?BR><BR>3、用的问题?BR><BR>如何才能比较方便C用?我考虑?jin)下面这U方式:(x)</P> <DIV style="BORDER-RIGHT: windowtext 0.5pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: windowtext 0.5pt solid; PADDING-LEFT: 5.4pt; BACKGROUND: #e6e6e6; PADDING-BOTTOM: 4px; BORDER-LEFT: windowtext 0.5pt solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: windowtext 0.5pt solid"> <DIV><SPAN style="COLOR: #000000">template (tng)</SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #0000ff">class</SPAN><SPAN style="COLOR: #000000"> (tng)T</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000"><BR></SPAN><SPAN style="COLOR: #0000ff">struct</SPAN><SPAN style="COLOR: #000000"> (tng)I(yng)Proxy;<BR><BR>template (tng)</SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #0000ff">class</SPAN><SPAN style="COLOR: #000000"> (tng)T</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000"><BR></SPAN><SPAN style="COLOR: #0000ff">struct</SPAN><SPAN style="COLOR: #000000"> (tng)SOAPProxy;<BR><BR>SOAPProxy (tng)</SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #000000">TestService</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000"> (tng)service;<BR>service.connect (tng)(</SPAN><SPAN style="COLOR: #000000">5000</SPAN><SPAN style="COLOR: #000000">, (tng)</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">localhost</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">);<BR></SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000"> (tng)a</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">0</SPAN><SPAN style="COLOR: #000000">;<BR></SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000"> (tng)</SPAN><SPAN style="COLOR: #000000">*</SPAN><SPAN style="COLOR: #000000">n (tng)</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000"> (tng)</SPAN><SPAN style="COLOR: #000000">&</SPAN><SPAN style="COLOR: #000000">a;<BR>service.test1 (tng)(</SPAN><SPAN style="COLOR: #000000">3</SPAN><SPAN style="COLOR: #000000">, (tng)n);<BR>service.test1 (tng)(</SPAN><SPAN style="COLOR: #000000">3</SPAN><SPAN style="COLOR: #000000">, (tng)</SPAN><SPAN style="COLOR: #000000">*</SPAN><SPAN style="COLOR: #000000">n);<BR>service.test2 (tng)(</SPAN><SPAN style="COLOR: #000000">3</SPAN><SPAN style="COLOR: #000000">, (tng)n);<BR>service.test2 (tng)(</SPAN><SPAN style="COLOR: #000000">3</SPAN><SPAN style="COLOR: #000000">, (tng)</SPAN><SPAN style="COLOR: #000000">*</SPAN><SPAN style="COLOR: #000000">n);<BR>service.test2 (tng)(</SPAN><SPAN style="COLOR: #000000">3</SPAN><SPAN style="COLOR: #000000">, (tng)NONE);<BR></SPAN><SPAN style="COLOR: #008000">//</SPAN><SPAN style="COLOR: #008000"><IMG src="http://www.shnenglu.com/images/dot.gif"></SPAN></DIV></DIV> <P><BR>Method::operator ()的各个参数都可以接受相容的cdQ像上面一P因ؓ(f)在TestService中我们已l定义了(jin)它要传输的值的cd?BR><BR>a.NONE是什么?其实是ؓ(f)异步调用考虑的。假如指定某个OUT参数为NONEQ则q个参数的值ƈ不真正的OUTQ而是保存在Method中。实际上Method中保存每个参数的倹{?BR><BR>b.Method与Service如何发生关系Q?BR>从TestService的定义中我们知道QMethod向Service注册自己以实现自省,但它同时也会(x)保存Service的指向?BR>我们的Proxy实际上是一个承模板,上面q没有把它指出来。它的定义是Q?/P> <DIV style="BORDER-RIGHT: windowtext 0.5pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: windowtext 0.5pt solid; PADDING-LEFT: 5.4pt; BACKGROUND: #e6e6e6; PADDING-BOTTOM: 4px; BORDER-LEFT: windowtext 0.5pt solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: windowtext 0.5pt solid"> <DIV><SPAN style="COLOR: #000000">template (tng)</SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #0000ff">class</SPAN><SPAN style="COLOR: #000000"> (tng)T</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000"><BR></SPAN><SPAN style="COLOR: #0000ff">class</SPAN><SPAN style="COLOR: #000000"> (tng)XProxy (tng): (tng)</SPAN><SPAN style="COLOR: #0000ff">public</SPAN><SPAN style="COLOR: #000000"> (tng)T<XPROXY><BR>{<BR> (tng) (tng) (tng) (tng)</SPAN><SPAN style="COLOR: #008000">//</SPAN><SPAN style="COLOR: #008000"><IMG src="http://www.shnenglu.com/images/dot.gif"></SPAN><SPAN style="COLOR: #008000"><BR></SPAN><SPAN style="COLOR: #000000">};</SPAN></DIV></DIV> <P><BR>所以我们的TestService其实也是模板c,它将使用XProxy中定义的序列化类。XProxy实现Service基类中序列化虚函C?qing)调用虚函数?BR><BR>当一个Method调用Ӟ它会(x)调用Service的序列化Q由于被重写?jin),所以调用的是XProxy中的序列化方法。这个方法会(x)把这个Method的各in/inout参数序列化,然后执行q程调用Q再把调用结果反序列化给inout/out参数?BR><BR>4、其它想法?BR><BR>在考虑上面的定义方式时Q我也考虑?jin)其它方式,主要是返回值处理的Ҏ(gu)Q简q如下?BR><BR>前面我们假设?jin)一D将被开放ؓ(f)q程服务的代码:(x)</P> <DIV style="BORDER-RIGHT: windowtext 0.5pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: windowtext 0.5pt solid; PADDING-LEFT: 5.4pt; BACKGROUND: #e6e6e6; PADDING-BOTTOM: 4px; BORDER-LEFT: windowtext 0.5pt solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: windowtext 0.5pt solid"> <DIV><SPAN style="COLOR: #0000ff">struct</SPAN><SPAN style="COLOR: #000000"> (tng)Test<BR>{<BR> (tng) (tng) (tng) (tng)</SPAN><SPAN style="COLOR: #0000ff">void</SPAN><SPAN style="COLOR: #000000"> (tng)test1 (tng)(</SPAN><SPAN style="COLOR: #008000">/*</SPAN><SPAN style="COLOR: #008000">in</SPAN><SPAN style="COLOR: #008000">*/</SPAN><SPAN style="COLOR: #000000"> (tng)</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000"> (tng)v1, (tng)</SPAN><SPAN style="COLOR: #008000">/*</SPAN><SPAN style="COLOR: #008000">in</SPAN><SPAN style="COLOR: #008000">*/</SPAN><SPAN style="COLOR: #000000"> (tng)</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">*</SPAN><SPAN style="COLOR: #000000"> (tng)v2);<BR> (tng) (tng) (tng) (tng)</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000"> (tng)test2 (tng)(</SPAN><SPAN style="COLOR: #008000">/*</SPAN><SPAN style="COLOR: #008000">in</SPAN><SPAN style="COLOR: #008000">*/</SPAN><SPAN style="COLOR: #000000"> (tng)</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">&</SPAN><SPAN style="COLOR: #000000"> (tng)v1, (tng)</SPAN><SPAN style="COLOR: #008000">/*</SPAN><SPAN style="COLOR: #008000">out</SPAN><SPAN style="COLOR: #008000">*/</SPAN><SPAN style="COLOR: #000000"> (tng)</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">*</SPAN><SPAN style="COLOR: #000000"> (tng)v2);<BR>};<BR><BR></SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000"> (tng)test_func (tng)(</SPAN><SPAN style="COLOR: #008000">/*</SPAN><SPAN style="COLOR: #008000">in</SPAN><SPAN style="COLOR: #008000">*/</SPAN><SPAN style="COLOR: #000000"> (tng)</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">*</SPAN><SPAN style="COLOR: #000000"> (tng)v1, (tng)</SPAN><SPAN style="COLOR: #008000">/*</SPAN><SPAN style="COLOR: #008000">inout</SPAN><SPAN style="COLOR: #008000">*/</SPAN><SPAN style="COLOR: #000000"> (tng)</SPAN><SPAN style="COLOR: #0000ff">string</SPAN><SPAN style="COLOR: #000000">*</SPAN><SPAN style="COLOR: #000000"> (tng)v2);</SPAN></DIV></DIV> <P><BR>在前面的做法中,我们的服务描q是攑֜那一l宏里面Q好处是不用改这D代码,坏处是代码定义的地方和描述不在一P协调可能?x)有一些不ѝ?BR><BR>我也考虑?jin)另一U做法:(x)<BR><BR></P> <DIV style="BORDER-RIGHT: windowtext 0.5pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: windowtext 0.5pt solid; PADDING-LEFT: 5.4pt; BACKGROUND: #e6e6e6; PADDING-BOTTOM: 4px; BORDER-LEFT: windowtext 0.5pt solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: windowtext 0.5pt solid"> <DIV><SPAN style="COLOR: #0000ff">struct</SPAN><SPAN style="COLOR: #000000"> (tng)Test<BR>{<BR> (tng) (tng) (tng) (tng)idl (tng)</SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #0000ff">void</SPAN><SPAN style="COLOR: #000000">(</SPAN><SPAN style="COLOR: #0000ff">in</SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000">, (tng)</SPAN><SPAN style="COLOR: #0000ff">in</SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000">)</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000"> (tng)test1 (tng)(</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000"> (tng)v1, (tng)</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">*</SPAN><SPAN style="COLOR: #000000"> (tng)v2);<BR> (tng) (tng) (tng) (tng)idl (tng)</SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">(</SPAN><SPAN style="COLOR: #0000ff">in</SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000">, (tng)</SPAN><SPAN style="COLOR: #0000ff">out</SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000">)</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000"> (tng)test2 (tng)(</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">&</SPAN><SPAN style="COLOR: #000000"> (tng)v1, (tng)</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">*</SPAN><SPAN style="COLOR: #000000"> (tng)v2);<BR>};<BR><BR>idl (tng)</SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">(</SPAN><SPAN style="COLOR: #0000ff">in</SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000">, (tng)inout</SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #0000ff">string</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000">) (tng)test_func (tng)</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">*</SPAN><SPAN style="COLOR: #000000"> (tng)v1, (tng)</SPAN><SPAN style="COLOR: #0000ff">string</SPAN><SPAN style="COLOR: #000000">*</SPAN><SPAN style="COLOR: #000000"> (tng)v2);</SPAN></DIV></DIV> <P><BR>对于实现代码Q只需要修改返回gؓ(f)void的函敎ͼ把return;修改为return VOID;Qƈ且ؓ(f)没有写此语句的分支加上此句?BR><BR>VOID是一个特D类型的?rn)态变量,专ؓ(f)voidq回值的函数讑֮?BR><BR>q种做法修改?jin)原有的代码Q不q在定义服务时可以节省一些工作:(x)</P> <DIV style="BORDER-RIGHT: windowtext 0.5pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: windowtext 0.5pt solid; PADDING-LEFT: 5.4pt; BACKGROUND: #e6e6e6; PADDING-BOTTOM: 4px; BORDER-LEFT: windowtext 0.5pt solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: windowtext 0.5pt solid"> <DIV><SPAN style="COLOR: #000000">BEGIN_SERVICE (tng)(TestService)<BR> (tng) (tng) (tng) (tng)METHOD (tng)(test1, (tng)</SPAN><SPAN style="COLOR: #000000">&</SPAN><SPAN style="COLOR: #000000">Test::test1)<BR> (tng) (tng) (tng) (tng)METHOD (tng)(test2, (tng)</SPAN><SPAN style="COLOR: #000000">&</SPAN><SPAN style="COLOR: #000000">Test::test2)<BR> (tng) (tng) (tng) (tng)METHOD (tng)(test_func, (tng)test_func)<BR><BR> (tng) (tng) (tng) (tng)BEGIN_DEFINE (tng)(TestService)<BR> (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)METHOD_DEFINE (tng)(test1, (tng)</SPAN><SPAN style="COLOR: #000000">&</SPAN><SPAN style="COLOR: #000000">Test::test1)<BR> (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)METHOD_DEFINE (tng)(test2, (tng)</SPAN><SPAN style="COLOR: #000000">&</SPAN><SPAN style="COLOR: #000000">Test::test2)<BR> (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)METHOD_DEFINE (tng)(test_func, (tng)test_func)<BR> (tng) (tng) (tng) (tng)END_DEFINE (tng)()<BR><BR>END_SERVICE (tng)()</SPAN></DIV></DIV> <P><BR>它所需要的函数cdQ将由函数指针推对{?BR><BR>在GQ+~译器下Q可以用typeof来获得函数指针的cd而不需要真得获得函数指针|不过目前仅仅在GQ+下可用。(Z说一下,typeof已经列入c++0xQ?BR><BR>最l我攑ּ?jin)这个想法,毕竟它要修改现有的代码,某些情况下这是不可能的,而且typeof目前也不能跨~译器?BR><BR>三、实现?BR><BR>老实说我现在q没有一份完整的或半完整的实玎ͼ大部分想法还在头脑中Q测试代码倒是写了(jin)不少Q主要是用来试上述x能否实现Q我惛_部分情况都已l测试了(jin)Q只需要有旉来把它实现出来?BR><BR>q是我近期要做的事之一Q争取月内把它做完Ş?/P><img src ="http://www.shnenglu.com/cpunion/aggbug/272.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.shnenglu.com/cpunion/" target="_blank">qiezi</a> 2005-09-15 01:27 <a href="http://www.shnenglu.com/cpunion/archive/2005/09/15/272.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss> <footer> <div class="friendship-link"> <p>лǵվܻԴȤ</p> <a href="http://www.shnenglu.com/" title="精品视频久久久久">精品视频久久久久</a> <div class="friend-links"> </div> </div> </footer> <a href="http://www.hy129.cn" target="_blank">99þþùƷС˵</a>| <a href="http://www.hqfood.com.cn" target="_blank">þþþһƷ</a>| <a href="http://www.help0.cn" target="_blank">vaþþþúݺ</a>| <a href="http://www.numakj.cn" target="_blank">޾Ʒþþþþþþþþþ</a>| <a href="http://www.sunriseydy.cn" target="_blank">þþþ޾Ʒ</a>| <a href="http://www.yoliuping.cn" target="_blank">˾Ʒþ޸岻</a>| <a href="http://www.fanglan-tech.cn" target="_blank">þþƷһպ</a>| <a href="http://www.phb321.cn" target="_blank">޾Ʒtvþþþþþþ </a>| <a href="http://www.musqm.cn" target="_blank">Ʒþ¶</a>| <a href="http://www.duopudz.cn" target="_blank">Ʒþþþþþþ</a>| <a href="http://www.uushipin.cn" target="_blank">ݺɫþ</a>| <a href="http://www.zheibvgsz.cn" target="_blank">þþþ޹</a>| <a href="http://www.kxw1.cn" target="_blank">ŷƷһƷþ</a>| <a href="http://www.newcr.cn" target="_blank">޹Ʒþþ</a>| <a href="http://www.sd2sc.com.cn" target="_blank">ܻƺ۵վþmimiɫ</a>| <a href="http://www.ivgh.cn" target="_blank">ɫվþþþۺywww</a>| <a href="http://www.9405.com.cn" target="_blank">޾ƷþëƬ</a>| <a href="http://www.hantong168.com.cn" target="_blank">һþ</a>| <a href="http://www.icalip2008.cn" target="_blank">þþƷAVɫ</a>| <a href="http://www.sh-yd.com.cn" target="_blank">˾Ʒþ޸岻 ˾Ʒþ޸岻 ˾Ʒþ </a>| <a href="http://www.talkvo.cn" target="_blank">ٸ޾þþþþ</a>| <a href="http://www.vmtkcxf.cn" target="_blank">Ļþ</a>| <a href="http://www.elzx.com.cn" target="_blank">ŷպĻþ</a>| <a href="http://www.timng.cn" target="_blank">ɫþþۺƷ</a>| <a href="http://www.hfdsbw.cn" target="_blank">Ʒþþþþù</a>| <a href="http://www.ode.net.cn" target="_blank">ƷۺϾþþþþ97</a>| <a href="http://www.ihxc.cn" target="_blank">AVþþƷɫ</a>| <a href="http://www.xn88.cn" target="_blank">Ѿþˬˬav</a>| <a href="http://www.gdlj2004.cn" target="_blank">ݹ97þ÷ѹۿ</a>| <a href="http://www.ahyjj.cn" target="_blank">Ӱһþҹײ </a>| <a href="http://www.bjhswt.com.cn" target="_blank">Ʒһþ</a>| <a href="http://www.jcfw-1.cn" target="_blank">91ƷۺϾþþƷ</a>| <a href="http://www.gmxd.net.cn" target="_blank">þþþAVۺ</a>| <a href="http://www.kxvd.cn" target="_blank">ɫۺϾþþĻ </a>| <a href="http://www.zenavo.cn" target="_blank">þþƷƵ</a>| <a href="http://www.qp8978.cn" target="_blank">ٸ޾þþþþ</a>| <a href="http://www.51saer.cn" target="_blank">þþþþAvӰԺ</a>| <a href="http://www.sdhaomai.cn" target="_blank">þҹӰԺѹۿ</a>| <a href="http://www.mijie5.cn" target="_blank">þ99ڹ</a>| <a href="http://www.wyj325.cn" target="_blank">99þþþƷѹۿ</a>| <a href="http://www.888happy.cn" target="_blank">þþþƷ鶹 </a>| <script> (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })(); </script> </body>