<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet type="text/xsl" href="http://feeds.qzone.qq.com/rss.xsl" version="1.0"?>
<rss version="2.0" xmlns:qz="http://qzone.qq.com">
<channel>
<title><![CDATA[▄︻┳一]]></title>
<description><![CDATA[58599886]]></description>
<link>http://58599886.qzone.qq.com</link>
<lastBuildDate>Wed, 25 Nov 2009 15:09:11 GMT</lastBuildDate>
<generator>Qzone</generator>
<language>zh-cn</language>
<copyright>Copyright (C), 2005-2008, Tencent Tech. Co., Ltd.</copyright>
<pubDate>Thu, 08 Oct 2009 06:43:58 GMT</pubDate>

<item>
<title><![CDATA[C#与Flash交互]]></title>
<link>http://58599886.qzone.qq.com/blog/1254984238</link>
<description><![CDATA[C#与Flash交互<br>前段日子公司要求做一个C#与Flash交互的东西，用来C#与短信猫通讯将数据传到Flash上显示与操作的应用。<br><br>第一步C#添加组件<br>打开VS2005-工具-选择工具箱项-COM组件-选择Shockwave Flash Object-确定<br>添加好组件往场景上拖放，如果提示注册需求注册<br>c# 注册控件-在运行输入-回车（flash9f.ocx这个文件以系统中实际文件为准。）<br>regsvr32 c:\windows\system32\macromed\flash\flash9f.ocx<br>或者regsvr32 c:\windows\system32\macromed\flash\flash10a.ocx<br><br><br>第二步将Flash组件拖入场景<br>将Flash组件拖入场景，设置加载的swf路径。设置组件id。<br>组件的Movie属性：指定要播放的swf的路径，<br>      如果swf在本地硬盘，则需要写成 从盘符开始的绝对路径<br>      如果swf在某网站上，则需要写成 完全的url网址<br><span style="color:#000080;line-height:1.8em;">更多该组件属性/方法<br><br></span><wbr />第三步AS代码片段<br>刚开始用FSCommand与网页VBSCRIPT做了一个通讯，以为这样就能与C#通讯了，结果错误了。<br>还得用ExternalInterface.addCallback，ExternalInterface.call的方法来与C#通讯。<br><br> 程序代码<br>import flash.external.*;<br>//向C#发送数据<br>ExternalInterface.call (&quot;test&quot;, &quot;str&quot;, Math.random ());<br>//接受C#发来的数据<br>ExternalInterface.addCallback (&quot;c2flash&quot;, null, c2flash);<br>function c2flash (s:String)<br>{<br>    out_txt.text = s;<br>}<br><br><br>第四步C#代码片段<br> 程序代码<br>private void Form1_Load(object sender, EventArgs e)<br>{<br>    flash.Movie = &quot;E:/c2flash.swf&quot;;<br>    flash.FlashCall += new AxShockwaveFlashObjects._IShockwaveFlashEvents_FlashCallEventHandler(flash_FlashCall);<br>}<br><br>void flash_FlashCall(object sender, AxShockwaveFlashObjects._IShockwaveFlashEvents_FlashCallEvent e)<br>{<br>    string s = nodeXml(e.request.ToString())[0].ChildNodes[0].InnerText.ToString();<br>    //接受Flash传来的值<br>    this.textBox1.Text = s;<br>    throw new Exception(&quot;The method or operation is not implemented.&quot;);    <br>}<br>private void button1_Click(object sender, EventArgs e)<br>{<br>    //向Flash发送数据<br>    callFunction(&quot;c2flash&quot;,this.textBox1.Text);<br>}<br>private void callFunction(string funName,string arg)<br>{<br>    //C#传给Flash的值<br>    flash.CallFunction(&quot;&lt;invoke name=\&quot;&quot; + funName + &quot;\&quot; returntype=\&quot;xml\&quot;&gt;&lt;arguments&gt;&lt;string&gt;&quot;+arg+&quot;&lt;/string&gt;&lt;/arguments&gt;&lt;/invoke&gt;&quot;);<br>}<br>private XmlNodeList nodeXml(string s)<br>{<br>    XmlDocument doc = new XmlDocument();<br>    doc.LoadXml(s);<br>    XmlNodeList list = doc.GetElementsByTagName(&quot;arguments&quot;);<br>    return list;<br>} <!--v:3.2--> ]]></description>
<category><![CDATA[c#]]></category>
<author><![CDATA[58599886@qq.com(▄︻┳一)]]></author>
<comments>http://58599886.qzone.qq.com/blog/1254984238#comment</comments>
<qz:effect>134218240</qz:effect>
<pubDate>Thu, 08 Oct 2009 06:43:58 GMT</pubDate>
<guid>http://58599886.qzone.qq.com/blog/1254984238</guid>
</item>

<item>
<title><![CDATA[.net中有关IE编程]]></title>
<link>http://58599886.qzone.qq.com/blog/1254219372</link>
<description><![CDATA[webbrowers 控件<br>打开网页，<br>Object url=&quot;http:///index2.asp&quot;;<br>   axWebBrowser1.Navigate2(ref url);<br>其中Navigate2方法比Navigate方法多了一些功能，比如打开文件夹（没试过）<br>NavigateComplete事件在DocumentComplete事件之前执行<br>已模似网页操作为例子<br>如果是做winform程序<br>比如你要进行打开网页，填写数据，点击提交等操作<br>下面代码<br>int cmdNum<br>private void button1_Click(object sender, System.EventArgs e)<br>  {<br>　Object url=&quot;http:///index2.asp&quot;;<br>   axWebBrowser1.Navigate2(ref url);<br>   }  private void Form1_Load(object sender, System.EventArgs e)<br>  {<br>//命令集合<br>   al=new ArrayList();<br>   al.Add(new command(1,&quot;staff_name_en&quot;,&quot;InputText&quot;,&quot;zuoqs&quot;));<br>   al.Add(new command(2,&quot;password&quot;,&quot;InputText&quot;,&quot;js020508&quot;));<br>   al.Add(new command(3,&quot;submit&quot;,&quot;submit&quot;,&quot;{enter}&quot;));<br>  }private void axWebBrowser1_DocumentComplete(object sender, AxSHDocVw.DWebBrowserEvents2_DocumentCompleteEvent e)<br>  {<br>   timer1.Enabled=false;//计时器暂停<br>   axWebBrowser1.Focus(); <br>   mshtml.HTMLDocumentClass doc=(mshtml.HTMLDocumentClass)axWebBrowser1.Document;<br>   if(doc.location.href.IndexOf(&quot;mis/index2.asp&quot;)&gt;-1)<br>    {<br>     if(doc.body.innerText.IndexOf(&quot;你不是合法用户&quot;)&gt;-1||doc.body.innerText.IndexOf(&quot;你的口令输入错误&quot;)&gt;-1)<br>     {<br>     label1.Text=&quot;登陆失败&quot;;<br>      timer1.Enabled=false;<br>      return;<br>     }<br>    }<br>   <br>   timer1.Enabled=true;//处理完逻辑后开启<br>  }  private void timer1_Tick(object sender, System.EventArgs e)<br>  {<br>   timer1.Enabled=false;//计时器暂停<br>   axWebBrowser1.Focus();//控件焦点获取<br>   if(cmdNum==al.Count)<br>   {<br>    timer1.Enabled=false;//如果命令执行完后计时器暂停<br>   }<br>   else<br>   {<br>    mshtml.HTMLDocumentClass doc=(mshtml.HTMLDocumentClass)axWebBrowser1.Document;<br>    command cmd = (command)al[cmdNum];<br>    switch (cmd.ElementType)<br>    {<br>          case &quot;InputText&quot;:<br>     {<br>      mshtml.HTMLInputTextElement element = (mshtml.HTMLInputTextElement)doc.all.item(cmd.ElementId,0);<br>      element.focus();//文本框获取焦点<br>      SendKeys.Send(cmd.CommandString);//模似键盘打字<br>      break;<br>     }<br>     case &quot;submit&quot;:<br>     {<br>      mshtml.HTMLInputButtonElement element = (mshtml.HTMLInputButtonElement)doc.all.item(cmd.ElementId,0);<br>      element.focus();<br>      SendKeys.Send(cmd.CommandString);//提交表单后，计时器关闭，等页面加载完后开启<br>      cmdNum++;<br>      timer1.Enabled=false;<br>      return;<br>      <br>     }<br>     case &quot;button&quot;:<br>     {<br>      mshtml.HTMLInputButtonElement element = (mshtml.HTMLInputButtonElement)doc.all.item(cmd.ElementId,0);<br>      element.focus();<br>      SendKeys.Send(cmd.CommandString);<br>      break;<br>     }<br>        cmdNum++;<br>    timer1.Enabled=true; //计时器开启<br>    <br>   }以上是基本方法，但会有一些问题<br>执行js脚本<br>  (mshtml.HTMLDocumentClass)axWebBrowser1.Document.parentWindow.execScript(&quot;alert()&quot;,&quot;javascript&quot;)<br>如果希望网页不会有alert,confirm,脚本报错等，可以使用下面的js脚本<br>window.alert=function(){}; window.confirm=function(){return true}; window.onerror=function(){return true};<br>屏蔽弹屏<br>private void axWebBrowser1_NewWindow3(object sender, AxSHDocVw.DWebBrowserEvents2_NewWindow3Event e)<br>  {<br>  e.cancel=true;<br>  }<br>弹屏在另一个webbrowers打开<br>private void axWebBrowser1_NewWindow2(object sender, AxSHDocVw.DWebBrowserEvents2_NewWindow2Event e)<br>  {<br>   e.ppDisp=axWebBrowser2.Application;<br>  }<br>访问iframe<br>mshtml.IHTMLWindow2 farme = (mshtml.IHTMLWindow2)doc.frames.item(ref main);<br>这里很关键的地方是用IHTMLWindow2而不是用mshtml.HTMLIFrame如果你是做类库，那你不能有可视的界面，那你也不能模似键盘的操作了，你需要用SHDocVw.dll，这个文件在system32里面，提供和webbrowers一样的功能<br>public void openIE2()<br>  {<br>  Thread t=new Thread(new ThreadStart(threadOpenIE));<br>    t.Name=&quot;changeorder&quot;;<br>    t.Start();  //用多线程，这样可以并行打开多个网页<br>   }<br>  public void threadOpenIE()<br>  {<br>   object   objFlags=0;   //0无页面，有缓存 1有页面，无缓存 <br>   object   objTargetFrameName=&quot;&quot;;   <br>   object   objPostData=&quot;&quot;;   <br>   object   objHeaders=&quot;User-Agent: Mozilla/4.0(compatible; MSIE 6.0; Windows NT 5.0)&quot;;   //可不写<br>   SHDocVw.InternetExplorerClass   a;<br>   try<br>   {<br>    a=new SHDocVw.InternetExplorerClass();<br>   }<br>   catch(Exception e)<br>   {<br>   a=null;<br>   throw e;<br>   System.Threading.Thread.CurrentThread.Abort();<br>   }<br>   a.Navigate(&quot;http://host/action/HTMLPage1.asp&quot;,ref   objFlags,ref   objTargetFrameName,ref   objPostData,ref   objHeaders);   //如果objFlags=0是不会弹出页面的，但可以把网页的dom对象保存在内存中，如果objFlags=1就会弹出ie,网页的内容也不会在内存中保存了<br>   while (a.Busy);//不断访问页面直到页面加载结束.这里指服务器的响应，而不是js代码，也就是说再复杂的js代码也不会影响a.busy的状态<br>   mshtml.HTMLDocumentClass doc=(mshtml.HTMLDocumentClass)a.Document;//如果objFlags=1就会报错<br>   mshtml.HTMLSelectElementClass　selectelement = (mshtml.HTMLSelectElementClass)doc.all.item(&quot;reser_status&quot;,0);<br>   selectelement.selectedIndex=2;//如果不知道index可以用selectelement.value=&quot;**&quot;;<br>   object aaa=null;<br>   selectelement.FireEvent(&quot;onchange&quot;,ref aaa);//因为无法模似键盘，所以页面上任何onchange类型js脚本无法运行，所以用FireEvent来激活onchange事件.<br>   mshtml.HTMLInputTextElement textelement = (mshtml.HTMLInputTextElement)doc.all.item(&quot;price_admin&quot;,0);<br>   textelement.value=textelement.value;<br>   mshtml.HTMLInputButtonElement element = (mshtml.HTMLInputButtonElement)doc.all.item(&quot;su&quot;,0);<br>//这里如果网页很大，可以不会一次取到，要取多次<br>//for (int i = 0; i &lt; times; i++)<br>//           {<br>//                if (Element == null)<br>//                    Element = doc.all.item(ElementName, index);<br>//                else<br>//                    break;<br>//            }<br>   element.click();<br>    while (a.Busy)<br>   {<br>   System.Threading.Thread.Sleep(500);//这样做可以减少访问页面的次数<br>   }<br>    while (a.ReadyState != SHDocVw.tagREADYSTATE.READYSTATE_COMPLETE)<br>   {<br>   System.Threading.Thread.Sleep(500);//a. busy等于fase的时候，页面也可能没有加载完，一定要有这步<br> }<br>   doc=(mshtml.HTMLDocumentClass)a.Document;<br>   string html=doc.body.innerHTML;<br>   a.Quit();<br>   <br>   System.Threading.Thread.CurrentThread.Abort();<br>  }<br>也许有个会问为什么不用DocumentComplete事件，因为这个事件无非是又开一个线程进行监听，作为类库程序，主线程很容易执行完，释放资源，DocumentComplete执行完后将无法找到原来调用它的线程，如果一定要用的话可以这样用.<br>a.DocumentComplete+=new SHDocVw.DWebBrowserEvents2_DocumentCompleteEventHandler(a_DocumentComplete);<br>System.Threading.Thread.Sleep(3000);// 主线程等待为了使a_DocumentComplete可以执行，但做为类库项目不建议这样做，我们可以发现一般需要监听其它资源的事件都是新开线程，当事件激活后，回调方法时，主线程应确保还在内存中存在.<br>多线程使用SHDocVw.dll会丧失很多功能，比如doucment里面的parentwindow,iframe,script等属性可以访问不到.<br>调用com组件有一个不好就是很多错误都是未指定错误，所以你不知道是因为什么出的错.看错误可以看comException类的hresult属性，com组件报的错都是个数字，可惜的是，很多数字微软都说成未指定错误.<br>关闭窗口方法<br>browers.quit();<br>用javascript方法<br>doc.parentWindow.opener=null;<br>doc.parentWindow.open(&quot;&quot;,&quot;_top&quot;,&quot;&quot;,false);<br>doc.parentWindow.close();<br>对于很多页面元素的操作，没有什么资料，完全靠试，比如遍历某个select的option<br>mshtml.HTMLSelectElementClass dd=(mshtml.HTMLSelectElementClass)doc.all.item(&quot;ddd&quot;,0);<br> mshtml.IHTMLElementCollection aaa= (mshtml.IHTMLElementCollection)dd.children;<br>//这里试了半天才试出来，HTMLSelectElementClass.options HTMLSelectElementClass.childnodes 都没有办法转化为IHTMLElementCollection　<br>如果是option集合，不要想利用IHTMLElementCollection.item(name,index)的方法遍历，因为option是没有name的，如果试图采用IHTMLElementCollection.item(null,index)不管你index是几，返回结果都是第一个元素.<br>要用foreach<br>foreach(mshtml.HTMLOptionElementClass option in aaa)<br>   {<br>    string sd= option.value+option.text;<br>   }<br>不过好像并不是所有的集合都可以foreach,不过在这里是可以用的<br>new一个SHDocVw.InternetExplorerClass();系统里面就会多一个iexplorer进程，记住一定要quit掉，用单例模式性能应该高点. <!--v:3.2--> ]]></description>
<category><![CDATA[c#]]></category>
<author><![CDATA[58599886@qq.com(▄︻┳一)]]></author>
<comments>http://58599886.qzone.qq.com/blog/1254219372#comment</comments>
<qz:effect>134218240</qz:effect>
<pubDate>Tue, 29 Sep 2009 10:16:12 GMT</pubDate>
<guid>http://58599886.qzone.qq.com/blog/1254219372</guid>
</item>

<item>
<title><![CDATA[C# 通过IE句柄 获得 IE Document对象和IWebBrowser2对象]]></title>
<link>http://58599886.qzone.qq.com/blog/1253854774</link>
<description><![CDATA[本来是做JAVA的，由于工作需要，最近做了一些C# 对网页的控制，<br>一直以来都是利用System.Windows.Forms.WebBrowser webBrowser1 来把网页嵌入到我的窗体内进行控制。而且控制起来非常方便。<br>有一个项目的网页比较特殊，目前我还不知道什么原因，他的网页会把我的程序挂起，没办法，只有利用跨进程获得IE对象了。<br>主要应用了 一个COM组件 三个引用 三个对象 来讲述这个简单的例子<br>1.COM组件 Microsoft.mshtml.dll 这个不用多说了，地球人都知道。<br>2.     using mshtml;//这。。。。。多说无用<br>　　using SHDocVw; //IWebBrowser2 是他下面的<br>        using System.Runtime.InteropServices; //DLL的引用，方法的重写3.IWebBrowser2 其实他要比WebBrowser 强大的多，正常我们直接用内嵌的浏览器对象，如果深入的朋友，在应用内嵌浏览器的时候也可以使用它来接受对象。<br>IShellWindows 呵呵。。。自己追踪下 就知道了。。都不用查<br>HTMLDocumentClass 这个本人也不求甚解，只知道他和 HTMLDocument差不多，只是方法名不太一样。。。<br>//---------------------------------------------------------------------------------<br>using System;<br>using System.Collections.Generic;<br>using System.ComponentModel;<br>using System.Data;<br>using System.Drawing;<br>using System.Text;<br>using System.Windows.Forms;<br>using mshtml;<br>using SHDocVw;<br>using System.Runtime.InteropServices;namespace dxzj<br>{<br>    public partial class Form1 : Form<br>    {<br>        [DllImport(&quot;user32&quot;, EntryPoint = &quot;FindWindow&quot;)]<br>        public static extern int FindWindowA(string lpClassName, string lpWindowName);<br>        public Form1()<br>        {<br>            InitializeComponent();<br>        }        private void timer1_Tick(object sender, EventArgs e)<br>        {        }<br>        //声明Document对象（如果用内嵌浏览器，我们得到的是一个HTMLDocument）<br>        HTMLDocumentClass document = null;<br>        private void button1_Click(object sender, EventArgs e)<br>        {<br>            //查找打开的窗口句柄<br>            int iehwnd = FindWindowA(null, &quot;用银行卡充值_中国联通 - Microsoft Internet Explorer&quot;);<br>            //初始化所有IE窗口<br>            IShellWindows sw = new ShellWindowsClass();<br>            //轮询所有IE窗口<br>            for (int i = sw.Count - 1; i &gt;= 0; i--)<br>            {<br>                //得到每一个IE的 IWebBrowser2 对象<br>                IWebBrowser2 iwb2 = sw.Item(i) as IWebBrowser2;<br>                //比对 得到的 句柄是否符合查找的窗口句柄<br>                if(iwb2.HWND == iehwnd)<br>                {<br>                    //查找成功 进行赋值<br>                    document = (HTMLDocumentClass)iwb2.Document;<br>                    //对网页进行操作<br>                    document.getElementById(&quot;directOnlinePayInfo.productNO&quot;).innerText = &quot;1111&quot;;<br>                }<br>            }<br>        }<br>    }<br>} <!--v:3.2--> ]]></description>
<category><![CDATA[c#]]></category>
<author><![CDATA[58599886@qq.com(▄︻┳一)]]></author>
<comments>http://58599886.qzone.qq.com/blog/1253854774#comment</comments>
<qz:effect>134218240</qz:effect>
<pubDate>Fri, 25 Sep 2009 04:59:34 GMT</pubDate>
<guid>http://58599886.qzone.qq.com/blog/1253854774</guid>
</item>

<item>
<title><![CDATA[C#中直接操作C++结构体]]></title>
<link>http://58599886.qzone.qq.com/blog/1252564574</link>
<description><![CDATA[在C#中调用C++或系统DLL是比较常见的操作。 <br>　　例如C++中定义的以下结构体： <br><wbr /><a href="http://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif" target="_blank"><img style="width:11px;height:16px;border:0;" src="http://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif" /></a><wbr /><wbr /><a href="http://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif" target="_blank"><img style="width:11px;height:16px;border:0;" src="http://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif" /></a><wbr />struct RCEStruct <wbr /><a href="http://www.cnblogs.com/Images/dot.gif" target="_blank"><img style="width:15px;height:20px;border:0;" src="http://www.cnblogs.com/Images/dot.gif" /></a><wbr />{ <br><wbr /><a href="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" target="_blank"><img style="width:11px;height:16px;border:0;" src="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" /></a><wbr /> int Event; <br><wbr /><a href="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" target="_blank"><img style="width:11px;height:16px;border:0;" src="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" /></a><wbr /> int Flag; <br><wbr /><a href="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" target="_blank"><img style="width:11px;height:16px;border:0;" src="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" /></a><wbr /> char User[40]; <br><wbr /><a href="http://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockEnd.gif" target="_blank"><img style="width:11px;height:16px;border:0;" src="http://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockEnd.gif" /></a><wbr />};　　同时有一个公开方法： <br>　　extern &quot;C&quot; __declspec WORD CALLBACK GetStruct(RCEStruct* pEventStruc); <br>　　我们将它编译为 MyCppDll.DLL <br><br>　　那么我们在C#中可以直接定义相同的结构体和引用GetStruct: <br><wbr /><a href="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" target="_blank"><img style="width:11px;height:16px;border:0;" src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" /></a><wbr />[StructLayout(LayoutKind.Sequential)] <br><wbr /><a href="http://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif" target="_blank"><img style="width:11px;height:16px;border:0;" src="http://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif" /></a><wbr /><wbr /><a href="http://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif" target="_blank"><img style="width:11px;height:16px;border:0;" src="http://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif" /></a><wbr />public struct RCEStruct <wbr /><a href="http://www.cnblogs.com/Images/dot.gif" target="_blank"><img style="width:15px;height:20px;border:0;" src="http://www.cnblogs.com/Images/dot.gif" /></a><wbr />{ <br><wbr /><a href="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" target="_blank"><img style="width:11px;height:16px;border:0;" src="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" /></a><wbr /> public int Event; <br><wbr /><a href="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" target="_blank"><img style="width:11px;height:16px;border:0;" src="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" /></a><wbr /> public int Flag; <br><wbr /><a href="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" target="_blank"><img style="width:11px;height:16px;border:0;" src="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" /></a><wbr /> public char[40] User; <br><wbr /><a href="http://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockEnd.gif" target="_blank"><img style="width:11px;height:16px;border:0;" src="http://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockEnd.gif" /></a><wbr />} <br><wbr /><a href="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" target="_blank"><img style="width:11px;height:16px;border:0;" src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" /></a><wbr /> <br><wbr /><a href="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" target="_blank"><img style="width:11px;height:16px;border:0;" src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" /></a><wbr />[DllImport(&quot;MyCppDll.dll&quot;, CharSet=CharSet.Auto)] <br><wbr /><a href="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" target="_blank"><img style="width:11px;height:16px;border:0;" src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" /></a><wbr />public static extern int GetStruct(RCEStruct rce);<br>　　注意C#里定义的结构体应该和C++里定义的一样。这里如果是public string User就有可能出错(具体我没试过，不知道C#是否会自动将char[]转变为string，另外还要注意，在C#中为User赋值时，长度不应超过40)。 <br>　　通过这种方式我们就可以向C++传递或者获得结构体。但一个限制就是必须在C#端主动调用GetStruct() <br><br>　　还有一种情况，与上一种相反，就是我们不是希望在C#中调用C++类库，而是想在C++类库中调用我们已经写好的C#类库。这在托管C++里是可以实现的。其中一个应用案例就是在为第三方系统写C++插件的时候，我们必须在插件端主动调用C#类库（前提是我们需要使用它，除非我们完全用C++代码来写这个插件）。 <br>　　这样的话我们应该是在C#类库公开方法，例如： <br><wbr /><a href="http://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif" target="_blank"><img style="width:11px;height:16px;border:0;" src="http://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif" /></a><wbr /><wbr /><a href="http://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif" target="_blank"><img style="width:11px;height:16px;border:0;" src="http://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif" /></a><wbr />public struct RCEStruct <wbr /><a href="http://www.cnblogs.com/Images/dot.gif" target="_blank"><img style="width:15px;height:20px;border:0;" src="http://www.cnblogs.com/Images/dot.gif" /></a><wbr />{ <br><wbr /><a href="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" target="_blank"><img style="width:11px;height:16px;border:0;" src="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" /></a><wbr /> public int Event; <br><wbr /><a href="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" target="_blank"><img style="width:11px;height:16px;border:0;" src="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" /></a><wbr /> public int Flag; <br><wbr /><a href="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" target="_blank"><img style="width:11px;height:16px;border:0;" src="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" /></a><wbr /> public string User; <br><wbr /><a href="http://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockEnd.gif" target="_blank"><img style="width:11px;height:16px;border:0;" src="http://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockEnd.gif" /></a><wbr />} <br><wbr /><a href="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" target="_blank"><img style="width:11px;height:16px;border:0;" src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" /></a><wbr /> <br><wbr /><a href="http://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif" target="_blank"><img style="width:11px;height:16px;border:0;" src="http://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif" /></a><wbr /><wbr /><a href="http://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif" target="_blank"><img style="width:11px;height:16px;border:0;" src="http://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif" /></a><wbr />public void DoSomething(RCEStruct rce)<wbr /><a href="http://www.cnblogs.com/Images/dot.gif" target="_blank"><img style="width:15px;height:20px;border:0;" src="http://www.cnblogs.com/Images/dot.gif" /></a><wbr />{ <br><wbr /><a href="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" target="_blank"><img style="width:11px;height:16px;border:0;" src="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" /></a><wbr /> rce.Flag++; <br><wbr /><a href="http://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockEnd.gif" target="_blank"><img style="width:11px;height:16px;border:0;" src="http://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockEnd.gif" /></a><wbr />}　　假定编译成 MyCSharpDll.DLL <br>　　C++端代码如下： <br><wbr /><a href="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" target="_blank"><img style="width:11px;height:16px;border:0;" src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" /></a><wbr />#using &lt;mscorlib.dll&gt; <br><wbr /><a href="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" target="_blank"><img style="width:11px;height:16px;border:0;" src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" /></a><wbr />#using &lt;CuteSuProc.dll&gt; <br><wbr /><a href="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" target="_blank"><img style="width:11px;height:16px;border:0;" src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" /></a><wbr /> <br><wbr /><a href="http://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif" target="_blank"><img style="width:11px;height:16px;border:0;" src="http://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif" /></a><wbr /><wbr /><a href="http://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif" target="_blank"><img style="width:11px;height:16px;border:0;" src="http://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif" /></a><wbr />void SomeMethod(RCEStruct* pEventStruc)<wbr /><a href="http://www.cnblogs.com/Images/dot.gif" target="_blank"><img style="width:15px;height:20px;border:0;" src="http://www.cnblogs.com/Images/dot.gif" /></a><wbr />{ <br><wbr /><a href="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" target="_blank"><img style="width:11px;height:16px;border:0;" src="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" /></a><wbr /> // 将C++结构体赋值到C#结构体 <br><wbr /><a href="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" target="_blank"><img style="width:11px;height:16px;border:0;" src="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" /></a><wbr /> MyCSharpDll::RCEStruct* csStruct; <br><wbr /><a href="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" target="_blank"><img style="width:11px;height:16px;border:0;" src="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" /></a><wbr /> csStruct-&gt;Event = pEventStruc.Event; <br><wbr /><a href="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" target="_blank"><img style="width:11px;height:16px;border:0;" src="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" /></a><wbr /> csStruct-&gt;Flag = pEventStruc.Flag; <br><wbr /><a href="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" target="_blank"><img style="width:11px;height:16px;border:0;" src="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" /></a><wbr /> // csStruct-&gt;User ?? 将char转换成string，在C++里如何处理？ <br><wbr /><a href="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" target="_blank"><img style="width:11px;height:16px;border:0;" src="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" /></a><wbr /> <br><wbr /><a href="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" target="_blank"><img style="width:11px;height:16px;border:0;" src="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" /></a><wbr /> MyCSharpDll::DoSomething(csStruct); <br><wbr /><a href="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" target="_blank"><img style="width:11px;height:16px;border:0;" src="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" /></a><wbr /> <br><wbr /><a href="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" target="_blank"><img style="width:11px;height:16px;border:0;" src="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" /></a><wbr /> // 将C#结构体赋值到C++结构体 <br><wbr /><a href="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" target="_blank"><img style="width:11px;height:16px;border:0;" src="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" /></a><wbr /> // 因为 pEventStruc 由外界传入，被 DoSomething 方法修改后，可能仍需要外界知道 <br><wbr /><a href="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" target="_blank"><img style="width:11px;height:16px;border:0;" src="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" /></a><wbr /> pEventStruc-&gt;Event = csStruct.Event; <br><wbr /><a href="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" target="_blank"><img style="width:11px;height:16px;border:0;" src="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" /></a><wbr /> pEventStruc-&gt;Flag = csStruct.Flag; <br><wbr /><a href="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" target="_blank"><img style="width:11px;height:16px;border:0;" src="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" /></a><wbr /> // pEventStruc-&gt;User ?? 将string转换成char[] <br><wbr /><a href="http://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockEnd.gif" target="_blank"><img style="width:11px;height:16px;border:0;" src="http://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockEnd.gif" /></a><wbr />}　　托管C++在处理.NET类库时，有些细节是很繁琐的，让人觉得有些晕乎。譬如很多地方要加__gc修饰符。还有像数组，字符串的转换都比较麻烦。所以上面代码可能会有些小错误。但大致意思就是这样。很明显，这样的做法非常麻烦。对结构体进行操作前，我们进行一次赋值，操作后，又进行一次赋值。 <br>　　有没有办法直接让C#操作原始的结构体呢？就像C#中操作C++一样，不需要通过一个中间人？能不能直接这样： <br><wbr /><a href="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" target="_blank"><img style="width:11px;height:16px;border:0;" src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" /></a><wbr />#using &lt;mscorlib.dll&gt; <br><wbr /><a href="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" target="_blank"><img style="width:11px;height:16px;border:0;" src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" /></a><wbr />#using &lt;CuteSuProc.dll&gt; <br><wbr /><a href="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" target="_blank"><img style="width:11px;height:16px;border:0;" src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" /></a><wbr /> <br><wbr /><a href="http://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif" target="_blank"><img style="width:11px;height:16px;border:0;" src="http://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif" /></a><wbr /><wbr /><a href="http://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif" target="_blank"><img style="width:11px;height:16px;border:0;" src="http://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif" /></a><wbr />void SomeMethod(RCEStruct* pEventStruc)<wbr /><a href="http://www.cnblogs.com/Images/dot.gif" target="_blank"><img style="width:15px;height:20px;border:0;" src="http://www.cnblogs.com/Images/dot.gif" /></a><wbr />{ <br><wbr /><a href="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" target="_blank"><img style="width:11px;height:16px;border:0;" src="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" /></a><wbr /> MyCSharpDll::DoSomething(pEventStruc); <br><wbr /><a href="http://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockEnd.gif" target="_blank"><img style="width:11px;height:16px;border:0;" src="http://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockEnd.gif" /></a><wbr />}　　答案是否定的。我们没有办法直接将C++里的 RCEStruct转换为 C#里的 RCEStruct。 <br><br>　　那么还剩一种方法，就是直接对内存进行操作。因为是结构体，他们肯定是保存在连续内存空间中的。 <br>　　我们先来看看C#中如何操作内存，也就是非托管的数据。这需要引用System.Runtime.InteropServices命名空间。该命名空间下的Marshal的一些静态方法提供了这样的功能： <br><wbr /><a href="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" target="_blank"><img style="width:11px;height:16px;border:0;" src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" /></a><wbr />Marshal.ReadInt32() //从指定内存地址读取4位 <br><wbr /><a href="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" target="_blank"><img style="width:11px;height:16px;border:0;" src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" /></a><wbr />Marshal.PtrToStringAnsi() //从指定内存地址读取字符串 <br><wbr /><a href="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" target="_blank"><img style="width:11px;height:16px;border:0;" src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" /></a><wbr />Marshal.WriteInt32() //将整数写到指定内存地址 <br><wbr /><a href="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" target="_blank"><img style="width:11px;height:16px;border:0;" src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" /></a><wbr />Marshal.WriteByte() //将字符串写到指定内存地址　　我们来看看具体的代码： <br><wbr /><a href="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" target="_blank"><img style="width:11px;height:16px;border:0;" src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" /></a><wbr />using System; <br><wbr /><a href="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" target="_blank"><img style="width:11px;height:16px;border:0;" src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" /></a><wbr />using System.Text; <br><wbr /><a href="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" target="_blank"><img style="width:11px;height:16px;border:0;" src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" /></a><wbr />using System.Runtime.InteropServices; <br><wbr /><a href="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" target="_blank"><img style="width:11px;height:16px;border:0;" src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" /></a><wbr /> <br><wbr /><a href="http://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif" target="_blank"><img style="width:11px;height:16px;border:0;" src="http://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif" /></a><wbr /><wbr /><a href="http://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif" target="_blank"><img style="width:11px;height:16px;border:0;" src="http://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif" /></a><wbr />internal sealed class RCEvent <wbr /><a href="http://www.cnblogs.com/Images/dot.gif" target="_blank"><img style="width:15px;height:20px;border:0;" src="http://www.cnblogs.com/Images/dot.gif" /></a><wbr />{ <br><wbr /><a href="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" target="_blank"><img style="width:11px;height:16px;border:0;" src="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" /></a><wbr /> public int Event; <br><wbr /><a href="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" target="_blank"><img style="width:11px;height:16px;border:0;" src="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" /></a><wbr /> public int Flag; <br><wbr /><a href="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" target="_blank"><img style="width:11px;height:16px;border:0;" src="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" /></a><wbr /> public string User; <br><wbr /><a href="http://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockEnd.gif" target="_blank"><img style="width:11px;height:16px;border:0;" src="http://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockEnd.gif" /></a><wbr />}; <br><wbr /><a href="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" target="_blank"><img style="width:11px;height:16px;border:0;" src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" /></a><wbr /> <br><wbr /><a href="http://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif" target="_blank"><img style="width:11px;height:16px;border:0;" src="http://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif" /></a><wbr /><wbr /><a href="http://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif" target="_blank"><img style="width:11px;height:16px;border:0;" src="http://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif" /></a><wbr />internal sealed class RCEventAgent <wbr /><a href="http://www.cnblogs.com/Images/dot.gif" target="_blank"><img style="width:15px;height:20px;border:0;" src="http://www.cnblogs.com/Images/dot.gif" /></a><wbr />{ <br><wbr /><a href="http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif" target="_blank"><img style="width:11px;height:16px;border:0;" src="http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif" /></a><wbr /><wbr /><a href="http://www.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif" target="_blank"><img style="width:11px;height:16px;border:0;" src="http://www.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif" /></a><wbr /> internal static RCEvent Read(IntPtr ptr)<wbr /><a href="http://www.cnblogs.com/Images/dot.gif" target="_blank"><img style="width:15px;height:20px;border:0;" src="http://www.cnblogs.com/Images/dot.gif" /></a><wbr />{ <br><wbr /><a href="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" target="_blank"><img style="width:11px;height:16px;border:0;" src="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" /></a><wbr /> RCEvent Event = new RCEvent(); <br><wbr /><a href="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" target="_blank"><img style="width:11px;height:16px;border:0;" src="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" /></a><wbr /> <br><wbr /><a href="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" target="_blank"><img style="width:11px;height:16px;border:0;" src="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" /></a><wbr /> Event.Event = ReadEvent(ptr); <br><wbr /><a href="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" target="_blank"><img style="width:11px;height:16px;border:0;" src="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" /></a><wbr /> Event.Flag = ReadFlag(ptr); <br><wbr /><a href="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" target="_blank"><img style="width:11px;height:16px;border:0;" src="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" /></a><wbr /> Event.User = ReadUser(ptr); <br><wbr /><a href="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" target="_blank"><img style="width:11px;height:16px;border:0;" src="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" /></a><wbr /> <br><wbr /><a href="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" target="_blank"><img style="width:11px;height:16px;border:0;" src="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" /></a><wbr /> return Event; <br><wbr /><a href="http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif" target="_blank"><img style="width:11px;height:16px;border:0;" src="http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif" /></a><wbr /> } <br><wbr /><a href="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" target="_blank"><img style="width:11px;height:16px;border:0;" src="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" /></a><wbr /> <br><wbr /><a href="http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif" target="_blank"><img style="width:11px;height:16px;border:0;" src="http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif" /></a><wbr /><wbr /><a href="http://www.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif" target="_blank"><img style="width:11px;height:16px;border:0;" src="http://www.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif" /></a><wbr /> internal static int ReadEvent(IntPtr basePtr) <wbr /><a href="http://www.cnblogs.com/Images/dot.gif" target="_blank"><img style="width:15px;height:20px;border:0;" src="http://www.cnblogs.com/Images/dot.gif" /></a><wbr />{ <br><wbr /><a href="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" target="_blank"><img style="width:11px;height:16px;border:0;" src="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" /></a><wbr /> return Marshal.ReadInt32(basePtr); <br><wbr /><a href="http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif" target="_blank"><img style="width:11px;height:16px;border:0;" src="http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif" /></a><wbr /> } <br><wbr /><a href="http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif" target="_blank"><img style="width:11px;height:16px;border:0;" src="http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif" /></a><wbr /><wbr /><a href="http://www.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif" target="_blank"><img style="width:11px;height:16px;border:0;" src="http://www.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif" /></a><wbr /> internal static int ReadFlag(IntPtr basePtr) <wbr /><a href="http://www.cnblogs.com/Images/dot.gif" target="_blank"><img style="width:15px;height:20px;border:0;" src="http://www.cnblogs.com/Images/dot.gif" /></a><wbr />{ <br><wbr /><a href="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" target="_blank"><img style="width:11px;height:16px;border:0;" src="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" /></a><wbr /> return Marshal.ReadInt32(basePtr,4); <br><wbr /><a href="http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif" target="_blank"><img style="width:11px;height:16px;border:0;" src="http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif" /></a><wbr /> } <br><wbr /><a href="http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif" target="_blank"><img style="width:11px;height:16px;border:0;" src="http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif" /></a><wbr /><wbr /><a href="http://www.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif" target="_blank"><img style="width:11px;height:16px;border:0;" src="http://www.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif" /></a><wbr /> internal static string ReadUser(IntPtr basePtr) <wbr /><a href="http://www.cnblogs.com/Images/dot.gif" target="_blank"><img style="width:15px;height:20px;border:0;" src="http://www.cnblogs.com/Images/dot.gif" /></a><wbr />{ <br><wbr /><a href="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" target="_blank"><img style="width:11px;height:16px;border:0;" src="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" /></a><wbr /> return Marshal.PtrToStringAnsi(new IntPtr(basePtr.ToInt32() + 8)); <br><wbr /><a href="http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif" target="_blank"><img style="width:11px;height:16px;border:0;" src="http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif" /></a><wbr /> } <br><wbr /><a href="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" target="_blank"><img style="width:11px;height:16px;border:0;" src="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" /></a><wbr /> <br><wbr /><a href="http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif" target="_blank"><img style="width:11px;height:16px;border:0;" src="http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif" /></a><wbr /><wbr /><a href="http://www.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif" target="_blank"><img style="width:11px;height:16px;border:0;" src="http://www.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif" /></a><wbr /> internal static void Write(ClientEvent Event,IntPtr ptr) <wbr /><a href="http://www.cnblogs.com/Images/dot.gif" target="_blank"><img style="width:15px;height:20px;border:0;" src="http://www.cnblogs.com/Images/dot.gif" /></a><wbr />{ <br><wbr /><a href="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" target="_blank"><img style="width:11px;height:16px;border:0;" src="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" /></a><wbr /> WriteEvent(ptr,Event.Event); <br><wbr /><a href="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" target="_blank"><img style="width:11px;height:16px;border:0;" src="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" /></a><wbr /> WriteFlag(ptr,Event.Flag); <br><wbr /><a href="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" target="_blank"><img style="width:11px;height:16px;border:0;" src="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" /></a><wbr /> WriteUser(ptr,Event.User); <br><wbr /><a href="http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif" target="_blank"><img style="width:11px;height:16px;border:0;" src="http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif" /></a><wbr /> } <br><wbr /><a href="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" target="_blank"><img style="width:11px;height:16px;border:0;" src="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" /></a><wbr /> <br><wbr /><a href="http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif" target="_blank"><img style="width:11px;height:16px;border:0;" src="http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif" /></a><wbr /><wbr /><a href="http://www.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif" target="_blank"><img style="width:11px;height:16px;border:0;" src="http://www.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif" /></a><wbr /> internal static void WriteEvent(IntPtr basePtr,int value) <wbr /><a href="http://www.cnblogs.com/Images/dot.gif" target="_blank"><img style="width:15px;height:20px;border:0;" src="http://www.cnblogs.com/Images/dot.gif" /></a><wbr />{ <br><wbr /><a href="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" target="_blank"><img style="width:11px;height:16px;border:0;" src="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" /></a><wbr /> Marshal.WriteInt32(basePtr,value); <br><wbr /><a href="http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif" target="_blank"><img style="width:11px;height:16px;border:0;" src="http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif" /></a><wbr /> } <br><wbr /><a href="http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif" target="_blank"><img style="width:11px;height:16px;border:0;" src="http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif" /></a><wbr /><wbr /><a href="http://www.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif" target="_blank"><img style="width:11px;height:16px;border:0;" src="http://www.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif" /></a><wbr /> internal static void WriteFlag(IntPtr basePtr,int flag) <wbr /><a href="http://www.cnblogs.com/Images/dot.gif" target="_blank"><img style="width:15px;height:20px;border:0;" src="http://www.cnblogs.com/Images/dot.gif" /></a><wbr />{ <br><wbr /><a href="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" target="_blank"><img style="width:11px;height:16px;border:0;" src="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" /></a><wbr /> Marshal.WriteInt32(basePtr,4,flag); <br><wbr /><a href="http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif" target="_blank"><img style="width:11px;height:16px;border:0;" src="http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif" /></a><wbr /> } <br><wbr /><a href="http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif" target="_blank"><img style="width:11px;height:16px;border:0;" src="http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif" /></a><wbr /><wbr /><a href="http://www.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif" target="_blank"><img style="width:11px;height:16px;border:0;" src="http://www.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif" /></a><wbr /> internal static void WriteUser(IntPtr basePtr,string user) <wbr /><a href="http://www.cnblogs.com/Images/dot.gif" target="_blank"><img style="width:15px;height:20px;border:0;" src="http://www.cnblogs.com/Images/dot.gif" /></a><wbr />{ <br><wbr /><a href="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" target="_blank"><img style="width:11px;height:16px;border:0;" src="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" /></a><wbr /> WriteString(basePtr,user,8,40); <br><wbr /><a href="http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif" target="_blank"><img style="width:11px;height:16px;border:0;" src="http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif" /></a><wbr /> } <br><wbr /><a href="http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif" target="_blank"><img style="width:11px;height:16px;border:0;" src="http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif" /></a><wbr /><wbr /><a href="http://www.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif" target="_blank"><img style="width:11px;height:16px;border:0;" src="http://www.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif" /></a><wbr /> private static void WriteString(IntPtr basePtr,string value,int offset,int length) <wbr /><a href="http://www.cnblogs.com/Images/dot.gif" target="_blank"><img style="width:15px;height:20px;border:0;" src="http://www.cnblogs.com/Images/dot.gif" /></a><wbr />{ <br><wbr /><a href="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" target="_blank"><img style="width:11px;height:16px;border:0;" src="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" /></a><wbr /> int pos = 0; <br><wbr /><a href="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" target="_blank"><img style="width:11px;height:16px;border:0;" src="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" /></a><wbr /> byte[] bytes = Encoding.Default.GetBytes(value); <br><wbr /><a href="http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif" target="_blank"><img style="width:11px;height:16px;border:0;" src="http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif" /></a><wbr /><wbr /><a href="http://www.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif" target="_blank"><img style="width:11px;height:16px;border:0;" src="http://www.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif" /></a><wbr /> while(pos &lt; length) <wbr /><a href="http://www.cnblogs.com/Images/dot.gif" target="_blank"><img style="width:15px;height:20px;border:0;" src="http://www.cnblogs.com/Images/dot.gif" /></a><wbr />{ <br><wbr /><a href="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" target="_blank"><img style="width:11px;height:16px;border:0;" src="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" /></a><wbr /> if (pos &lt; bytes.Length) <br><wbr /><a href="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" target="_blank"><img style="width:11px;height:16px;border:0;" src="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" /></a><wbr /> Marshal.WriteByte(basePtr,offset,bytes[pos]); <br><wbr /><a href="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" target="_blank"><img style="width:11px;height:16px;border:0;" src="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" /></a><wbr /> else <br><wbr /><a href="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" target="_blank"><img style="width:11px;height:16px;border:0;" src="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" /></a><wbr /> Marshal.WriteByte(basePtr,offset,0); <br><wbr /><a href="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" target="_blank"><img style="width:11px;height:16px;border:0;" src="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" /></a><wbr /> <br><wbr /><a href="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" target="_blank"><img style="width:11px;height:16px;border:0;" src="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" /></a><wbr /> pos ++; <br><wbr /><a href="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" target="_blank"><img style="width:11px;height:16px;border:0;" src="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" /></a><wbr /> offset ++; <br><wbr /><a href="http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif" target="_blank"><img style="width:11px;height:16px;border:0;" src="http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif" /></a><wbr /> } <br><wbr /><a href="http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif" target="_blank"><img style="width:11px;height:16px;border:0;" src="http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif" /></a><wbr /> } <br><wbr /><a href="http://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockEnd.gif" target="_blank"><img style="width:11px;height:16px;border:0;" src="http://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockEnd.gif" /></a><wbr />}　　这样我们就可以通过ReadEvent和WriteEvent直接在c#中处理该结构体。或者通过 ReadXXX() 和 WriteXXX() 直接修改其字段。 <br><wbr /><a href="http://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif" target="_blank"><img style="width:11px;height:16px;border:0;" src="http://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif" /></a><wbr /><wbr /><a href="http://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif" target="_blank"><img style="width:11px;height:16px;border:0;" src="http://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif" /></a><wbr />public void DoSomething(IntPtr ptr)<wbr /><a href="http://www.cnblogs.com/Images/dot.gif" target="_blank"><img style="width:15px;height:20px;border:0;" src="http://www.cnblogs.com/Images/dot.gif" /></a><wbr />{ <br><wbr /><a href="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" target="_blank"><img style="width:11px;height:16px;border:0;" src="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" /></a><wbr /> RCEvent Event = RCEventAgent.Read(ptr); <br><wbr /><a href="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" target="_blank"><img style="width:11px;height:16px;border:0;" src="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" /></a><wbr /> Event.Flag ++; <br><wbr /><a href="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" target="_blank"><img style="width:11px;height:16px;border:0;" src="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" /></a><wbr /> RCEventAgent.Write(ptr, Event); <br><wbr /><a href="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" target="_blank"><img style="width:11px;height:16px;border:0;" src="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" /></a><wbr /> <br><wbr /><a href="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" target="_blank"><img style="width:11px;height:16px;border:0;" src="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" /></a><wbr /> // 或者以下代码 <br><wbr /><a href="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" target="_blank"><img style="width:11px;height:16px;border:0;" src="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" /></a><wbr /> // RCEventAgent.WriteFlag( ptr, RCEventAgent.ReadFlag(ptr) + 1 ); <br><wbr /><a href="http://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockEnd.gif" target="_blank"><img style="width:11px;height:16px;border:0;" src="http://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockEnd.gif" /></a><wbr />}　　C++中则可以直接将结构体地址传给C#： <br><wbr /><a href="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" target="_blank"><img style="width:11px;height:16px;border:0;" src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" /></a><wbr />#using &lt;mscorlib.dll&gt; <br><wbr /><a href="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" target="_blank"><img style="width:11px;height:16px;border:0;" src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" /></a><wbr />#using &lt;CuteSuProc.dll&gt; <br><wbr /><a href="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" target="_blank"><img style="width:11px;height:16px;border:0;" src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" /></a><wbr /> <br><wbr /><a href="http://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif" target="_blank"><img style="width:11px;height:16px;border:0;" src="http://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif" /></a><wbr /><wbr /><a href="http://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif" target="_blank"><img style="width:11px;height:16px;border:0;" src="http://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif" /></a><wbr />void SomeMethod(RCEStruct* pEventStruc)<wbr /><a href="http://www.cnblogs.com/Images/dot.gif" target="_blank"><img style="width:15px;height:20px;border:0;" src="http://www.cnblogs.com/Images/dot.gif" /></a><wbr />{ <br><wbr /><a href="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" target="_blank"><img style="width:11px;height:16px;border:0;" src="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" /></a><wbr /> MyCSharpDll::DoSomething(pEventStruc); <br><wbr /><a href="http://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockEnd.gif" target="_blank"><img style="width:11px;height:16px;border:0;" src="http://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockEnd.gif" /></a><wbr />} <!--v:3.2--> ]]></description>
<category><![CDATA[c#]]></category>
<author><![CDATA[58599886@qq.com(▄︻┳一)]]></author>
<comments>http://58599886.qzone.qq.com/blog/1252564574#comment</comments>
<qz:effect>134218241</qz:effect>
<pubDate>Thu, 10 Sep 2009 06:36:14 GMT</pubDate>
<guid>http://58599886.qzone.qq.com/blog/1252564574</guid>
</item>

<item>
<title><![CDATA[C#调用C++写的dll，包含结构体转换和C#动态调用dll]]></title>
<link>http://58599886.qzone.qq.com/blog/1252563503</link>
<description><![CDATA[<span style="font-size:13px;line-height:1.8em;"><span style="font-family:'宋体';line-height:1.8em;">这段时间用C++给客户做了一个通讯的dll。但客户是用C#的，所以研究了下C#，把C++的头文件，改写成C#的。主要是转换了结构体的定义，dll函数的调用，C#中的dll的动态调用，C++和C#之间的时间变量的传递。现在和大家分享一下。<br><br><span style="color:#ff0000;line-height:1.8em;">C++的头文件：</span><wbr /><br><br>#pragma once<br>//<br>//设置 <br>//<br>typedef struct _RMusterSettings<br>{<br>   DWORD dwDataSize; <br>   RComm Comm; <br>   RCoData CoData; <br>   double RealClock; <br>   WORD MeterCount; <br>   WORD RecNoMax; <br>   struct _RAutoReadSettings<br>   {<br>       BYTE Enable;<br>       BYTE Days[31];<br>       struct _RARTime<br>       {<br>           BYTE Enable;<br>           BYTE Hour;<br>           BYTE Min;<br>           BYTE Sec;<br>       <br>       }Time[24];<br>   } RAutoReadSettings;<br>} RMusterSettings;<br>//<br>//通讯类定义<br>//<br>typedef HANDLE (*CREATEXXXXCOMM)();<br>typedef INT (*FREEXXXXCOMM)(HANDLE);<br>typedef INT (*XXXXCOMM)(HANDLE,WORD,void *);<br>typedef INT (*XXXXABORT)(HANDLE);<br>class CXXXXComm<br>{<br>private:<br>   HINSTANCE           hLib;<br>   HANDLE               hXXXXComm; <br>   CREATEXXXXCOMM       fnCreateXXXXComm;<br>   FREEXXXXCOMM       fnFreeXXXXComm;<br>   XXXXCOMM           fnXXXXComm;<br>   XXXXABORT            fnXXXXAbort;<br>public:<br>   CXXXXComm(PCHAR fileName)<br>   {<br>       hLib = LoadLibrary(fileName); <br>       if (hLib != NULL)<br>       {<br>           fnCreateXXXXComm   = (CREATEXXXXCOMM) GetProcAddress(hLib, &quot;CreateXXXXComm&quot;); <br>           fnFreeXXXXComm      = (FREEXXXXCOMM) GetProcAddress(hLib, &quot;FreeXXXXComm&quot;); <br>           fnXXXXComm          = (XXXXCOMM) GetProcAddress(hLib, &quot;XXXXComm&quot;); <br>           fnXXXXAbort       = (XXXXABORT) GetProcAddress(hLib, &quot;XXXXAbort&quot;); <br>           hXXXXComm           = fnCreateXXXXComm();<br>       }<br>   };<br>   ~CXXXXComm()<br>   {<br>       if (hLib != NULL)<br>       {<br>           fnFreeXXXXComm(hXXXXComm);<br>           FreeLibrary(hLib);<br>       }<br>   };<br>   INT Comm(WORD cmd, void * data)<br>   {<br>       if (hLib != NULL)<br>           return fnXXXXComm(hXXXXComm,cmd,data);<br>       else<br>           return EC_DLL_NOT_FOUND;<br>   };<br>   INT Abort()<br>   {<br>       if (hLib != NULL)<br>           return fnXXXXAbort(hXXXXComm);<br>       else<br>           return 0;<br>   };<br>};<br><br><br><span style="color:#ff0000;line-height:1.8em;">C#的类文件</span><wbr /><br><br>using System;<br>using System.Runtime.InteropServices;<br>namespace Flagele.rd.CXXXXComm<br>{<br>    //<br>    //设置 <br>    //<br>    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]<br>    public struct RARTime<br>    {<br>        public byte Enable; <br>        public byte Hour; <br>        public byte Min; <br>        public byte Sec; <br>    }        <br>    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]<br>    public struct RAutoReadSettings<br>    {<br>       <br>        public byte     Enable; <br>        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 31)]<br>        public byte[]   Days; <br>        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 24)]<br>        public RARTime[] Time; <br>    }        <br>    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]<br>    public class RMusterSettings<br>    {<br>        public uint     dwDataSize;<br>        public RComm    Comm; <br>        public RCoData CoData; <br>        //<br>        public long     RealClock; <br>        public ushort   MeterCount; <br>        public ushort   RecNoMax; <br>        public RAutoReadSettings ARSettings; <br>    } <br>     //<br>    //通讯类<br>    //<br>    public class CXXXXComm<br>    {<br>        private uint hLib;<br>        private uint hXXXXComm;<br>        private delegate uint CREATEXXXXCOMM();<br>        private delegate uint FREEXXXXCOMM(uint hFe);<br>        private delegate uint XXXXCOMM(uint hFe, ushort cmd, [In,Out,MarshalAs(UnmanagedType.AsAny)] Object data);<br>        private delegate uint XXXXABORT(uint hFe);<br>        private CREATEXXXXCOMM fnCreateXXXXComm;<br>        private FREEXXXXCOMM fnFreeXXXXComm;<br>        private XXXXCOMM fnXXXXComm;<br>        private XXXXABORT fnXXXXAbort;<br>        [DllImport(&quot;Kernel32&quot;)]<br>        private static extern uint GetProcAddress(uint handle, String funcname);<br>        [DllImport(&quot;Kernel32&quot;)]<br>        private static extern uint LoadLibrary(String funcname);<br>        [DllImport(&quot;Kernel32&quot;)]<br>        private static extern uint FreeLibrary(uint handle);<br>        private static Delegate GetAddress(uint dllModule, string functionname, Type t)<br>        {<br>            uint addr = GetProcAddress(dllModule, functionname);<br>            if (addr == 0)<br>                return null;<br>            else<br>                return Marshal.GetDelegateForFunctionPointer(new IntPtr(addr), t);<br>        }<br>        public CXXXXComm()<br>        {<br>            hLib = LoadLibrary(&quot;XXXXComm.dll&quot;);<br>            if (hLib != 0)<br>            {<br>                fnCreateXXXXComm = (CREATEXXXXCOMM)GetAddress(hLib, &quot;CreateXXXXComm&quot;, typeof(CREATEXXXXCOMM));<br>                fnFreeXXXXComm = (FREEXXXXCOMM)GetAddress(hLib, &quot;FreeXXXXComm&quot;, typeof(FREEXXXXCOMM));<br>                fnXXXXComm = (XXXXCOMM)GetAddress(hLib, &quot;XXXXComm&quot;, typeof(XXXXCOMM));<br>                fnXXXXAbort = (XXXXABORT)GetAddress(hLib, &quot;XXXXAbort&quot;, typeof(XXXXABORT));<br>                if (fnCreateXXXXComm != null)<br>                {<br>                    hXXXXComm = fnCreateXXXXComm();<br>                }<br>            }<br>        }<br>        ~CXXXXComm()<br>        {<br>            if (fnFreeXXXXComm != null)<br>            {<br>                fnFreeXXXXComm(hXXXXComm);<br>            }<br>            if (hLib != 0)<br>            {<br>                FreeLibrary(hLib);<br>            }<br>        }<br>        public uint comm(ushort cmd, [MarshalAs(UnmanagedType.AsAny)] Object data)<br>        {<br>            if (hLib != 0)<br>            {<br>                return fnXXXXComm(hXXXXComm, cmd, data);<br>            }<br>            else<br>                return CFeError.EC_DLL_NOT_FOUND;<br>        }<br>        public uint abort()<br>        {<br>            if (hLib != 0)<br>            {<br>                return fnXXXXAbort(hXXXXComm);<br>            }<br>            else<br>                return 0;<br>        }<br>    }<br>}<br><br><span style="color:#ff0000;line-height:1.8em;">C#的调用例子</span><wbr /><br><span style="font-weight:bold"><wbr /><span style="font-weight:bold"><wbr />//事先要创建XXXXComm<span style="font-weight:bold"><wbr />//private CXXXXComm XXXXComm;<span style="font-weight:bold"><wbr />//public Form1()<span style="font-weight:bold"><wbr />//{<span style="font-weight:bold"><wbr />//    InitializeComponent();<span style="font-weight:bold"><wbr />//    XXXXComm= new CXXXXComm();<span style="font-weight:bold"><wbr />//}<span style="font-weight:bold"><wbr /><span style="font-weight:bold"><wbr />//<span style="font-weight:bold"><wbr />//▼写设置<span style="font-weight:bold"><wbr />//<span style="font-weight:bold"><wbr />         mustersettings.ARSettings.Enable = 1;<span style="font-weight:bold"><wbr />         for (i = 0; i &lt; 31; i++)<span style="font-weight:bold"><wbr />         mustersettings.ARSettings.Days<span style="font-style:italic"><wbr /> = 1;<span style="font-weight:bold"><wbr />         for (i = 0; i &lt; 24; i++)<span style="font-weight:bold"><wbr />         {<span style="font-weight:bold"><wbr />                  mustersettings.ARSettings.Time<span style="font-style:italic"><wbr />.Enable = 0;<span style="font-weight:bold"><wbr />                  mustersettings.ARSettings.Time<span style="font-style:italic"><wbr />.Hour = (byte)i;<span style="font-weight:bold"><wbr />                  mustersettings.ARSettings.Time<span style="font-style:italic"><wbr />.Min = 0;<span style="font-weight:bold"><wbr />                  mustersettings.ARSettings.Time<span style="font-style:italic"><wbr />.Sec = 0;<span style="font-weight:bold"><wbr />         }<span style="font-weight:bold"><wbr />         Rec = XXXXComm.comm(CFeCmd.W_MusterAutoRead,(Object)mustersettings);<span style="font-weight:bold"><wbr />         if (Rec == 0)<span style="font-weight:bold"><wbr />         {<span style="font-weight:bold"><wbr />                  //成功<span style="font-weight:bold"><wbr />         }</span><wbr /></span><wbr /><span style="font-weight:bold"><wbr /> <!--v:3.2--> ]]></description>
<category><![CDATA[c#]]></category>
<author><![CDATA[58599886@qq.com(▄︻┳一)]]></author>
<comments>http://58599886.qzone.qq.com/blog/1252563503#comment</comments>
<qz:effect>134218240</qz:effect>
<pubDate>Thu, 10 Sep 2009 06:18:23 GMT</pubDate>
<guid>http://58599886.qzone.qq.com/blog/1252563503</guid>
</item>

<item>
<title><![CDATA[C#中调用带回调函数和自定义结构体的DLL例程]]></title>
<link>http://58599886.qzone.qq.com/blog/1252563200</link>
<description><![CDATA[开发环境: WinXP Pro(SP2英文版) + VS.NET 2003中文版<br>接口库版本: CMPP2.0 API第二版(V2.6)<br>该例程演示了如何在C#里面调用VC6.0开发的带回调函数的API，而且回调函数的参数包含结构体，使用C#的委托和IntPtr方法实现.<br>由于我使用C#刚两天,这是我写的第一个C#程序,因此例程写的可能有点粗糙,但是编译和运行完全没有问题. <br>CMPP2.0的API封装成了标准C调用的方法，提供以下三个接口，使用的时候只要有CMPPAPI.dll就可以了.<br>#define DllExport extern &quot;C&quot; __declspec(dllexport)<br>DllExport int __stdcall Cmpp2Start(LPCTSTR pchSmgIp, int nMtPort, int nMoPort, \<br>LPCTSTR pchUserName, LPCTSTR pchUserPwd, unsigned char uchVersion, \<br>void (__stdcall *OnSmgMsg)(CMPP_SMGTOSP* css), int nConnType, void (__stdcall *OnLogFile)(LPCTSTR str));<br>DllExport int __stdcall Cmpp2Submit(unsigned char uchPKtotal, unsigned char uchPKnumber, \<br>unsigned char uchNeedreport, unsigned char uchMsglevel, LPCTSTR pchServiceid, \<br>unsigned char uchFeeusertype, LPCTSTR pchFeeterminalid, unsigned char uchTppid, \<br>unsigned char uchTpudhi, unsigned char uchMsgfmt, LPCTSTR pchMsgsrc, \<br>LPCTSTR pchFeetype, LPCTSTR pchFeecode, LPCTSTR pchValidtime, \<br>LPCTSTR pchAttime, LPCTSTR pchSrcid, unsigned char uchDestusrtl, \<br>LPCTSTR pchDestterminalid, unsigned char uchMsglen, LPCTSTR pchMsgcontent);<br>DllExport int __stdcall Cmpp2Release();<br>在C#里面如何调用API,如何声明结构体,如何使用委托实现回调函数,如何实现使用自定义结构体作为参数的回调函数,请仔细查看例程源码。注意:CMPPAPI.dll要和可执行文件放到同一个目录下,或者放到可执行文件能找到的目录,或者放到系统目录下(如:C:\windows\system32).<br>下面是C#下面的完整的调用代码//Class1.cs<br>using System;<br>// 该名称空间包含了在Visual C#中调用API的一些必要集合<br>using System.Runtime.InteropServices;<br>// 使用Sleep方法需要的命名空间<br>using System.Threading;namespace CMPPAPI_Sample_CSharp<br>{<br>//---------------------------------------------------------------------<br>//---------以下是DLL中需要使用的结构体的定义---------------------------<br>//--------Pack = 1表示结构体按一个字节对齐----------------------------<br>[StructLayout(LayoutKind.Sequential, Pack = 1)]<br>public struct CMPP_HEAD <br>{<br>public uint nTotalLength;<br>public uint nCommandId;<br>public uint nSeqId;<br>}[StructLayout(LayoutKind.Sequential, Pack = 1)]<br>public struct CMPP_CONNECT <br>{<br>[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 6)] <br>public string sSourceAddr;<br>[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 16)] <br>public string sAuthSource;<br>public byte cVersion;<br>public uint nTimeStamp;<br>}[StructLayout(LayoutKind.Sequential, Pack = 1)]<br>public struct CMPP_CONNECT_RESP <br>{<br>public byte uchStatus;<br>[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 16)] <br>public string sAuthISMG;<br>public byte cVersion;<br>}[StructLayout(LayoutKind.Sequential, Pack = 1)]<br>public struct CMPP_SUBMIT_RESP <br>{<br>public long nMsgid;<br>public byte uchResult;<br>}[StructLayout(LayoutKind.Sequential, Pack = 1)]<br>public struct CMPP_STATUS_REPORT <br>{<br>public long nMsgid;<br>[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 7)] <br>public string sStat;<br>[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 10)] <br>public string sSubmitTime;<br>[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 10)] <br>public string sDoneTime;<br>[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 21)] <br>public string sDestTerminalId;<br>public uint nSmscSeq;<br>}[StructLayout(LayoutKind.Sequential, Pack = 1)]<br>public struct CMPP_MO_MSGCONTENT<br>{<br>[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 160)]<br>public string sMsgcontent;<br>public CMPP_STATUS_REPORT csr;<br>}[StructLayout(LayoutKind.Sequential, Pack = 1)]<br>public struct CMPP_DELIVER <br>{<br>public long nMsgid;<br>[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 21)] <br>public string sDestid;<br>[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 10)] <br>public string sServiceid;<br>public byte uchTppid;<br>public byte uchTpudhi;<br>public byte uchMsgfmt;<br>[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 21)] <br>public string sSrcterminalid;<br>public byte uchRegisteredDelivery;<br>public byte uchMsglength;public CMPP_MO_MSGCONTENT mo_msg;<br>[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 8)] <br>public string sReserved;<br>}[StructLayout(LayoutKind.Sequential, Pack = 1)]<br>public struct CMPP_SUBMIT <br>{<br>public long nMsgid;<br>public byte uchPkTotal;<br>public byte uchPkNumber;<br>public byte uchRegisteredDelivery;<br>public byte uchMsgLevel;<br>[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 10)] <br>public string sServiceId;<br>public byte uchFeeUserType;<br>[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 21)] <br>public string sFeeTerminalId;<br>public byte uchTpPid;<br>public byte uchTpUdhi;<br>public byte uchMsgFmt;<br>[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 6)] <br>public string sMsgSrc;<br>[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 2)] <br>public string sFeeType;<br>[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 6)] <br>public string sFeeCode;<br>[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 17)] <br>public string sValidTime;<br>[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 17)] <br>public string sAtTime;<br>[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 21)] <br>public string sSrcId;<br>public byte uchDstUsrTl;<br>[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 21*100)] <br>public string sDstTerminalId;<br>public byte uchMsgLength;<br>[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 160)] <br>public string sMsgContent;<br>[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 8)] <br>public string sReserved;<br>}[StructLayout(LayoutKind.Sequential, Pack = 1)]<br>public struct CMPP_QUERY <br>{<br>[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 8)] <br>public string sTime;<br>public byte uchQueryType;<br>[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 10)] <br>public string sQueryCode;<br>[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 8)] <br>public string sReserved;<br>}[StructLayout(LayoutKind.Sequential, Pack = 1)]<br>public struct CMPP_QUERY_RESP <br>{<br>[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 8)] <br>public string sTime;<br>public byte uchQueryType;<br>[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 10)] <br>public string sQueryCode;<br>public uint nMTTLMsg; //从SP接收消息总数.<br>public uint nMTTLUsr; //从SP接收用户总数.<br>public uint nMTScs; //成功转发数量.<br>public uint nMTWT; //待转发数量.<br>public uint nMTFL; //转发失败数量.<br>public uint nMOScs; //向SP成功送达数量.<br>public uint nMOWT; //向SP待送达数量.<br>public uint nMOFL; //向SP送达失败数量.<br>}[StructLayout(LayoutKind.Sequential, Pack = 1)]<br>public struct CMPP_CANCEL <br>{<br>public long nMsgid;<br>}[StructLayout(LayoutKind.Sequential, Pack = 1)]<br>public struct CMPP_CANCEL_RESP <br>{<br>public byte uchSuccessId;<br>}[StructLayout(LayoutKind.Sequential, Pack = 1)]<br>public struct CMPP_ACTIVETEST_RESP <br>{<br>public byte uchReserved;<br>}[StructLayout(LayoutKind.Sequential, Pack = 1)]<br>public struct CMPP_BODY<br>{<br>public CMPP_CONNECT_RESP pk_connectresp;<br>public CMPP_SUBMIT_RESP pk_submitresp;<br>public CMPP_QUERY_RESP pk_queryresp;<br>public CMPP_DELIVER pk_deliver;<br>public CMPP_CANCEL_RESP pk_cancelresp;<br>public CMPP_ACTIVETEST_RESP pk_activetestresp;<br>}[StructLayout(LayoutKind.Sequential, Pack = 1)]<br>public struct CMPP_SMGTOSP <br>{<br>public CMPP_HEAD pk_head;<br>public CMPP_BODY pk_body;<br>}<br>//----------------DLL需要使用的结构体的定义----------------------------<br>//---------------------------------------------------------------------<br>//----------------声明两个委托,相当于VC里面的回调函数------------------<br>public delegate void OnSmgMsg(IntPtr css);<br>public delegate void OnLogMsg(string str);<br>//---------------------------------------------------------------------class Class1<br>{<br>//--------------------------------------------------------------------------<br>//--------------DLL中的API函数声明------------------------------------------<br>// 1.Start Func<br>[DllImport(&quot;CMPPAPI.dll&quot;)] <br>public static extern int Cmpp2Start(string pchSmgIp, int nMtPort, int nMoPort, <br>string pchUserName, string pchUserPwd, byte uchVersion, <br>OnSmgMsg pf, int nConnType, OnLogMsg pf2);// 2.Submit Func<br>[DllImport(&quot;CMPPAPI.dll&quot;)] <br>public static extern int Cmpp2Submit(byte uchPKtotal, byte uchPKnumber,<br>byte uchNeedreport, byte uchMsglevel, string pchServiceid,<br>byte uchFeeusertype, string pchFeeterminalid, byte uchTppid,<br>byte uchTpudhi, byte uchMsgfmt, string pchMsgsrc,<br>string pchFeetype, string pchFeecode, string pchValidtime,<br>string pchAttime, string pchSrcid, byte uchDestusrtl,<br>string pchDestterminalid, byte uchMsglen, string pchMsgcontent);// 3.Release<br>[DllImport(&quot;CMPPAPI.dll&quot;)] <br>public static extern int Cmpp2Release();<br>//--------------DLL中的API函数声明------------------------------------------<br>//--------------------------------------------------------------------------//-------------这儿使用IntPtr实现与结构体之间的转换----------------<br>public static void OnMsg(IntPtr ptr) <br>{<br>CMPP_SMGTOSP css = new CMPP_SMGTOSP();<br>css = (CMPP_SMGTOSP)Marshal.PtrToStructure(ptr, typeof(CMPP_SMGTOSP));uint nCmdId = css.pk_head.nCommandId;<br>Console.WriteLine(css.pk_head.nCommandId);<br>if ( nCmdId == 0x80000004) {<br>// Submit应答消息<br>}<br>else if ( nCmdId == 0x0000005) {<br>// Deliver消息<br>}return;<br>}//------------第二个委托函数的定义-------------------------------<br>public static void OnLog(string str) <br>{<br>Console.WriteLine(str);<br>return;<br>}/// <br>/// 应用程序的主入口点。<br>/// <br>[STAThread]<br>static void Main(string[] args)<br>{<br>Class1 c1 = new Class1();<br>OnSmgMsg pt = new OnSmgMsg(OnMsg);<br>OnLogMsg pLog = new OnLogMsg(OnLog);//-------------启动模块,连接网关,收到消息以后会触发OnSmgMsg函数------------------------------<br>int nRetCode = Cmpp2Start(&quot;127.0.0.1&quot;, 7890, 7891, &quot;901234&quot;, &quot;1234&quot;, (byte)0x20, pt, 0, pLog);<br>if ( 0 == nRetCode) <br>{<br>Console.WriteLine(&quot;Connect Smg success\n&quot;);while ( true) <br>{<br>//----------向网关提交Submit消息----------<br>nRetCode = Cmpp2Submit(1, 1,<br>1, 3, &quot;2939&quot;,<br>0, &quot;&quot;, 0,<br>0, 0, &quot;901234&quot;,<br>&quot;02&quot;, &quot;000020&quot;, &quot;&quot;,<br>&quot;&quot;, &quot;01850&quot;, 1,<br>&quot;8613660617374&quot;, 8, &quot;测试消息&quot;);if ( 0 == nRetCode)<br>{<br>Console.WriteLine(&quot;Submit Success.&quot;);<br>}<br>else {<br>Console.WriteLine(&quot;Submit Fail.&quot;);<br>}// Sleep5秒钟<br>Thread.Sleep(5000);<br>}//-----释放连接-----<br>Cmpp2Release();<br>}<br>else {<br>Console.WriteLine(&quot;Connect SMG Fail With Error: &quot; + nRetCode);<br>}<br>}<br>}<br>} <!--v:3.2--> ]]></description>
<category><![CDATA[c#]]></category>
<author><![CDATA[58599886@qq.com(▄︻┳一)]]></author>
<comments>http://58599886.qzone.qq.com/blog/1252563200#comment</comments>
<qz:effect>134218240</qz:effect>
<pubDate>Thu, 10 Sep 2009 06:13:20 GMT</pubDate>
<guid>http://58599886.qzone.qq.com/blog/1252563200</guid>
</item>

<item>
<title><![CDATA[《Effective C#》学习笔记（六）--C#和C++结构体Socket通信]]></title>
<link>http://58599886.qzone.qq.com/blog/1252562980</link>
<description><![CDATA[Socket发送消息的时候遇到了服务端需要接收C++结构体的二进制数据流，这个时候就需要用C#仿照C++的结构体做出一个结构来，然后将其转换成二进制流进行发送，之后将响应消息的二进制数据流转换成C#结构。<br>1、仿照C++结构体写出C#的结构来<br> 1 using System.Runtime.InteropServices;<br> 2 <br> 3     [Serializable] // 指示可序列化<br> 4     [StructLayout(LayoutKind.Sequential, Pack = 1)] // 按1字节对齐<br> 5     public struct Operator<br> 6 <br> 7     {<br> 8          public ushort id;<br> 9         [MarshalAs(UnmanagedType.ByValArray, SizeConst = 11)] // 声明一个字符数组，大小为11<br>10         public char[] name;<br>11         [MarshalAs(UnmanagedType.ByValArray, SizeConst = 9)]<br>12         public char[] pass;<br>13 <br>14          public Operator(string user, string pass) // 初始化<br>15          {<br>16             this.id = 10000;<br>17             this.name = user.PadRight(11, '\0').ToCharArray();<br>18             this.pass = pass.PadRight(9, '\0').ToCharArray();<br>19         }<br>20     }<br>    2、注意C#与C++数据类型的对应关系<br>C++与C#的数据类型对应关系表<br>API数据类型 类型描述 C#类型 API数据类型 类型描述 C#类型<br>WORD 16位无符号整数 ushort CHAR 字符 char<br>LONG 32位无符号整数 int DWORDLONG 64位长整数 long<br>DWORD 32位无符号整数 uint HDC 设备描述表句柄 int<br>HANDLE 句柄,32位整数 int HGDIOBJ GDI对象句柄 int<br>UINT 32位无符号整数 uint HINSTANCE 实例句柄 int<br>BOOL 32位布尔型整数 bool HWM 窗口句柄 int<br>LPSTR 指向字符的32位指针 string HPARAM 32位消息参数 int<br>LPCSTR 指向常字符的32位指针 String LPARAM 32位消息参数 int<br>BYTE 字节 byte WPARAM 32位消息参数 int<br>整个结构的字节数是22bytes。<br>对应的C++结构体是：<br>1 typedef struct<br>2{<br>3      WORD id;            <br>4     CHAR name[11];<br>5     CHAR password[9];<br>6 }Operator;<br>3、发送的时候先要把结构转换成字节数组<br> 1  using System.Runtime.InteropServices;     <br> 2          /// &lt;summary&gt;<br> 4         /// 将结构转换为字节数组<br> 5         /// &lt;/summary&gt;<br> 6         /// &lt;param name=&quot;obj&quot;&gt;结构对象&lt;/param&gt;<br> 7         /// &lt;returns&gt;字节数组&lt;/returns&gt;<br> 8         public byte[] StructToBytes(object obj)<br> 9          {<br>10             //得到结构体的大小<br>11             int size = Marshal.SizeOf(obj);<br>12             //创建byte数组<br>13             byte[] bytes = new byte[size];<br>14             //分配结构体大小的内存空间<br>15             IntPtr structPtr = Marshal.AllocHGlobal(size);<br>16             //将结构体拷到分配好的内存空间<br>17             Marshal.StructureToPtr(obj, structPtr, false);<br>18             //从内存空间拷到byte数组<br>19             Marshal.Copy(structPtr, bytes, 0, size);<br>20             //释放内存空间<br>21             Marshal.FreeHGlobal(structPtr);<br>22             //返回byte数组<br>23             return bytes;<br>24 <br>25        }<br>26 <br>27 <br>接收的时候需要把字节数组转换成结构<br>        <br>  <br> 1      // &lt;summary&gt;<br> 2         /// byte数组转结构<br> 3         /// &lt;/summary&gt;<br> 4         /// &lt;param name=&quot;bytes&quot;&gt;byte数组&lt;/param&gt;<br> 5         /// &lt;param name=&quot;type&quot;&gt;结构类型&lt;/param&gt;<br> 6         /// &lt;returns&gt;转换后的结构&lt;/returns&gt;<br> 7         public object BytesToStruct(byte[] bytes, Type type)<br> 8          {<br> 9             //得到结构的大小<br>10             int size = Marshal.SizeOf(type);<br>11             Log(size.ToString(), 1);<br>12             //byte数组长度小于结构的大小<br>13             if (size &gt; bytes.Length)<br>14              {<br>15                 //返回空<br>16                 return null;<br>17             }<br>18             //分配结构大小的内存空间<br>19             IntPtr structPtr = Marshal.AllocHGlobal(size);<br>20             //将byte数组拷到分配好的内存空间<br>21             Marshal.Copy(bytes, 0, structPtr, size);<br>22             //将内存空间转换为目标结构<br>23             object obj = Marshal.PtrToStructure(structPtr, type);<br>24             //释放内存空间<br>25             Marshal.FreeHGlobal(structPtr);<br>26             //返回结构<br>27             return obj;<br>28         }<br>29 <br>4、实际操作：<br>  <br> 1 using System.Collections;<br> 2 using System.Collections.Generic;<br> 3 using System.Net;<br> 4 using System.Net.Sockets;<br> 5 <br> 6 byte[] Message = StructToBytes(new Operator(&quot;user&quot;,&quot;pass&quot;)); // 将结构转换成字节数组<br> 7 <br> 8 TcpClient socket = new TcpClient();<br> 9 <br>10 socket.Connect(ip,port);<br>11 <br>12 NetworkStream ns = Socket.GetStream();<br>13 <br>14 ns.Write(Message,0,Message.Length); // 发送<br>15 <br>16 byte[] Recv = new byte[1024]; // 缓冲<br>17 <br>18 int NumberOfRecv = 0;<br>19 <br>20 IList&lt;byte&gt; newRecv = new List&lt;byte&gt;();<br>21 ns.ReadTimeout = 3000;<br>22 try<br>23 {<br>24  do<br>25   {<br>26    // 接收响应<br>27    NumberOfRecv = ns.Read(Recv, 0, Recv.Length);<br>28    for (int i = 0; i &lt; NumberOfRecv; i++)<br>29    newRecv.Add(Recv<span style="font-style:italic"><wbr />);<br>30   }<br>31 while (ns.DataAvailable);<br>32 byte[] resultRecv = new byte[newRecv.Count];<br>33 newRecv.CopyTo(resultRecv, 0);<br>34 <br>35 Operator MyOper = new Operator();<br>36 <br>37 MyOper = (Operator)BytesToStruct(resultRecv, MyOper.GetType()); // 将字节数组转换成结构<br>38 <br>在这里取值的时候可能会出现只能取到一个字段，剩余的取不到的问题，怎么回事我也搞不懂，反正我的解决办法就是按照字节的顺序从resultRecv里分别取出对应的字段的字节数组，然后解码，例如：<br>Operator.name是11个字节，最后一位是0，Operator.id是2个字节，那么从第3位到第12位的字节就是Operator.name的内容，取出另存为一个数组MyOperName，Encoding.Default.GetString(MyOperName)就是MyOper.name的内容。<br>1 socket.Close();<br>2 <br>3 ns.Close();<br>4本文来自CSDN博客，转载请标明出处：<a href="http://blog.csdn.net/kaola2599/archive/2009/06/24/4294639.aspx" target="_blank">http://blog.csdn.net/kaola2599/archive/2009/06/24/4294639.aspx</a><wbr /><br> <!--v:3.2--> ]]></description>
<category><![CDATA[c#]]></category>
<author><![CDATA[58599886@qq.com(▄︻┳一)]]></author>
<comments>http://58599886.qzone.qq.com/blog/1252562980#comment</comments>
<qz:effect>134218240</qz:effect>
<pubDate>Thu, 10 Sep 2009 06:09:40 GMT</pubDate>
<guid>http://58599886.qzone.qq.com/blog/1252562980</guid>
</item>

<item>
<title><![CDATA[让人兴奋的新婚典礼]]></title>
<link>http://58599886.qzone.qq.com/blog/1251723440</link>
<description><![CDATA[<embed invokeURLs="false" allowNetworking="internal" allowscriptaccess="never" menu="false" id="flash0" width="260" height="185" src="http://p.you.video.sina.com.cn/player/outer_player.swf?auto=1&amp;vid=23080640&amp;uid=1290078633" /> <!--v:3.2--> ]]></description>
<category><![CDATA[天下杂侃]]></category>
<author><![CDATA[58599886@qq.com(▄︻┳一)]]></author>
<comments>http://58599886.qzone.qq.com/blog/1251723440#comment</comments>
<qz:effect>134222336</qz:effect>
<pubDate>Mon, 31 Aug 2009 12:57:20 GMT</pubDate>
<guid>http://58599886.qzone.qq.com/blog/1251723440</guid>
</item>

<item>
<title><![CDATA[[转]某高校寝室熄灯的壮观景象!!]]></title>
<link>http://58599886.qzone.qq.com/blog/1251720137</link>
<description><![CDATA[<embed invokeURLs="false" allowNetworking="internal" allowscriptaccess="never" menu="false" id="flash0" width="456" height="362" src="http://www.tudou.com/v/c12uNoFp2-c" /><br>这张帖你能忍住不转？？太牛了！！<br><br><span style="color:#cc3399;font-size:16px;line-height:1.8em;">壮观得不得了...不知道演练了多少次~~~!</span><wbr /><br><span style="color:#cc3399;font-size:16px;line-height:1.8em;">呵呵~~~</span><wbr /><br>------------------------------------------<br>本文转载自：<a href="http://user.qzone.qq.com/16820185/blog/1246774046" target="_blank">冯志锦： 某高校寝室熄灯的壮观景象!!</a><wbr /><br>用QQ邮箱阅读空间<a href="http://mail.qq.com/cgi-bin/feed?u=http://feeds.qzone.qq.com/cgi-bin/cgi_rss_out?uin=16820185" target="_blank">订阅<span style="font-weight:bold"><wbr />冯志锦</span><wbr /></a><wbr /><br><a href="http://mail.qq.com/zh_CN/htmledition/help_reader.html" target="_blank">什么是阅读空间?</a><wbr /><br>------------------------------------------<br>本文转载自：<a href="http://user.qzone.qq.com/312512635/blog/1246977296" target="_blank">-陳 冭冭： 转载：某高校寝室熄灯的壮观景象!!</a><wbr /><br>用QQ邮箱阅读空间<a href="http://mail.qq.com/cgi-bin/feed?u=http://feeds.qzone.qq.com/cgi-bin/cgi_rss_out?uin=312512635" target="_blank">订阅<span style="font-weight:bold"><wbr />-陳 冭冭</span><wbr /></a><wbr /><br><a href="http://mail.qq.com/zh_CN/htmledition/help_reader.html" target="_blank">什么是阅读空间?</a><wbr /> <!--v:3.2--> ]]></description>
<category><![CDATA[天下杂侃]]></category>
<author><![CDATA[58599886@qq.com(▄︻┳一)]]></author>
<comments>http://58599886.qzone.qq.com/blog/1251720137#comment</comments>
<qz:effect>5128</qz:effect>
<pubDate>Mon, 31 Aug 2009 12:02:17 GMT</pubDate>
<guid>http://58599886.qzone.qq.com/blog/1251720137</guid>
</item>

<item>
<title><![CDATA[在C#中使用SendMessage]]></title>
<link>http://58599886.qzone.qq.com/blog/1251634697</link>
<description><![CDATA[SendMessage是一个在user32.dll中声明的API函数，在C#中导入如下： <br><br>using System.Runtime.InteropServices; <br>[DllImport(&quot;user32.dll&quot;, EntryPoint=&quot;SendMessageA&quot;)] <br>public static extern int SendMessage (IntPtr hwnd, int wMsg, IntPtr wParam, IntPtr lParam); <br>本文描述其参数 lParam 的用法，主要是数据类型之间的转化。 <br><br>● 一种最简单的处理方式是声明多个SendMessage函数(overload)，用所需的数据类型直接替换IntPtr。例如： <br><br>//声明: <br>[DllImport(&quot;user32.dll&quot;, EntryPoint=&quot;SendMessageA&quot;)] <br>private static extern int SendMessage (IntPtr hwnd, int wMsg, IntPtr wParam, string lParam); <br>[DllImport(&quot;user32.dll&quot;, EntryPoint=&quot;SendMessageA&quot;)] <br>private static extern int SendMessage (IntPtr hwnd, int wMsg, IntPtr wParam, ref Rectangle lParam); <br>//调用: <br>string s = &quot;hello, floodzhu&quot;; <br>SendMessage(this.textBox1.Handle, WM_SETTEXT, IntPtr.Zero, s); <br><br>Rectangle rect = new Rectangle(); <br>SendMessage(this.richTextBox1.Handle, EM_GETRECT, (IntPtr)0, ref rect); <br>● 对要求返回字符串的类型（out string）可以用 StringBuilder 代替，此时不需要 out/ref。例如： <br><br>[DllImport(&quot;user32.dll&quot;, EntryPoint=&quot;SendMessageA&quot;)] <br>private static extern int SendMessage (IntPtr hwnd, int wMsg, int wParam, StringBuilder lParam); <br>private void button1_Click(object sender, System.EventArgs e) <br>{ <br>const int buffer_size = 1024; <br>StringBuilder buffer = new StringBuilder(buffer_size); <br>SendMessage(this.textBox1.Handle, WM_GETTEXT, buffer_size, buffer); <br>//MessageBox.Show(buffer.ToString()); <br>} <br>● 如果想用 InPtr 类型统一处理的话，可以借助于 Marshal 或者 GCHandle 的相关方法。例如： <br><br>[DllImport(&quot;user32.dll&quot;, EntryPoint=&quot;SendMessageA&quot;)] <br>private static extern int SendMessage (IntPtr hwnd, int wMsg, IntPtr wParam, IntPtr lParam); <br><br>private void button2_Click(object sender, System.EventArgs e) <br>{ <br>Rectangle rect = new Rectangle(); <br>IntPtr buffer = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(Rectangle))); <br>Marshal.StructureToPtr(rect, buffer ,true); <br><br>SendMessage(this.richTextBox1.Handle, EM_GETRECT, (IntPtr)0, buffer); <br><br>rect = (Rectangle)Marshal.PtrToStructure(buffer, typeof(Rectangle)); <br><br>Marshal.FreeHGlobal(buffer); <br>} <br>或者 <br><br>private void button2_Click(object sender, System.EventArgs e) <br>{ <br>Rectangle rect = new Rectangle(); <br>GCHandle gch = GCHandle.Alloc(rect); <br><br>SendMessage(this.richTextBox1.Handle, EM_GETRECT, (IntPtr)0, (IntPtr)gch); <br>rect = (Rectangle)Marshal.PtrToStructure((IntPtr)gch, typeof(Rectangle)); <br><br>gch.Free(); <br>} <!--v:3.2--> ]]></description>
<category><![CDATA[c#]]></category>
<author><![CDATA[58599886@qq.com(▄︻┳一)]]></author>
<comments>http://58599886.qzone.qq.com/blog/1251634697#comment</comments>
<qz:effect>134218240</qz:effect>
<pubDate>Sun, 30 Aug 2009 12:18:17 GMT</pubDate>
<guid>http://58599886.qzone.qq.com/blog/1251634697</guid>
</item>

</channel>
</rss>

