xml地图|网站地图|网站标签 [设为首页] [加入收藏]
进程间通信,鱼龙混杂
分类:编程

View Code

参考文档:

c# 进程间同步实现 进程之间通讯的几种方法

学习之后(After Learning)

数据结构之后的学习能否开展得顺利,极大程度上取决于对于数据结构(Data Structures)理解得是否透彻,下一篇笔记应该是着重讲算法分析方面,Flag:这周末将第二篇笔记发出来。

 

使用SendMessage向另一进程发送WM_COPYDATA消息

学习之前(Before Learning)

数据结构作为CS课程中的重中之重(其实CS的所有课程都很重要),作为打开“数据结构及其操作”的一把钥匙,实在是不敢大意。学习了半个学期,之前因为活动和其他一些琐事,一直没有完整的时间来学习这门课程(比较习惯大段大段的时间来学习,碎片化的时间会让我感到极大的不舒服)。现在手头上的事情逐步地少了,拖拉了这么久的学习笔记也终于可以一片一片地Pop出来了。总感觉自己的数据结构成了最早Push进去最晚Pop出来的栈帧。

话不多说,笔记大概会有12篇左右,主要参看了如下资料:

1.MOOC-陈越、何钦铭教授主讲《数据结构》;

2.《Data Structures and Algorithm Analysis in C》-Mark Allen Weiss ;

3.《C Prime Plus 中文版》- Stephen Prata(云巅工作室 译)

  1 /*2048*/
  2 
  3 #include<stdio.h>
  4 #include<stdlib.h>
  5 #include<conio.h>
  6 #include<time.h>
  7 
  8 void print(void);/*显示游戏界面*/
  9 int add(void);/*对中间变量数组进行处理*/
 10 
 11 int code[4][4] =
 12    {
 13     {0,0,0,0},
 14     {0,0,0,0},
 15     {0,0,0,0},
 16     {0,0,0,0},
 17    };/*游戏中的16个格子*/
 18 int temp[5];/*中间变量*/
 19 int move = 0;/*移动次数*/
 20 int score = 0;/*分数*/
 21 
 22 
 23 
 24 int main(void)
 25 {
 26      int gameover = 0;/*判断游戏是否结束,1结束,0继续*/
 27      int i,j;
 28      int change = 1;/*判断格子中的数是否改变,0不变*/
 29      char input;
 30      srand((unsigned)time(NULL));/*设置随机数的起点*/
 31      while(gameover == 0)
 32          {
 33               if(change >= 1)/*仅当数发生改变时添加新数*/
 34                {
 35                     do
 36                      {
 37                           i=((unsigned)rand()) % 4;
 38                           j=((unsigned)rand()) % 4;
 39                      }while(code[i][j] != 0);
 40                     if(((unsigned)rand()) % 4 == 0)
 41                      {
 42                           code[i][j]=4;
 43                      }
 44                     else
 45                      {
 46                           code[i][j]=2;/*随机选一个空格填上2或4*/
 47                      }
 48                     move++;/*增加次数*/
 49                }
 50               print();/*显示*/
 51               input = getch();/*输入方向*/
 52               change = 0;
 53               switch(input)
 54                    {
 55                         case '0':/*退出*/
 56                                  printf("Are you sure to exit?(y/n)");
 57                                  input=getchar();
 58                                  if(input=='y'||input=='Y')
 59                                     exit(0);
 60                                  break;
 61 
 62                         case 'W':
 63 
 64                         case 'w':/*上*/
 65                                  for(j=0;j<=3;j++)
 66                                    {
 67                                         for(i=0;i<=3;i++)
 68                                           {
 69                                                temp[i]=code[i][j];/*把一列数移到中间变量*/
 70                                           }
 71                                         temp[4]=0;
 72                                         change += add();
 73                                         for(i=0;i<=3;i++)
 74                                           {
 75                                                code[i][j]=temp[i];/*把处理好的中间变量移回来*/
 76                                           }
 77                                     }
 78                                   break;
 79 
 80                         case 'A':
 81 
 82                         case 'a':/*左*/
 83                                  for(i=0;i<=3;i++)
 84                                    {
 85                                         for(j=0;j<=3;j++)
 86                                           {
 87                                                temp[j]=code[i][j];/*把一行数移到中间变量*/
 88                                           }
 89                                         temp[4]=0;
 90                                         change += add();
 91                                         for(j=0;j<=3;j++)
 92                                           {
 93                                                code[i][j]=temp[j];/*把处理好的中间变量移回来*/
 94                                           }
 95                                    }
 96                                  break;
 97 
 98                         case 'S':
 99 
100                         case 's':/*下*/
101                                  for(j=0;j<=3;j++)
102                                    {
103                                         for(i=0;i<=3;i++)
104                                           {
105                                                temp[i]=code[3-i][j];/*把一列数移到中间变量*/
106                                           }
107                                         temp[4]=0;
108                                         change += add();
109                                         for(i=0;i<=3;i++)
110                                           {
111                                                code[3-i][j]=temp[i];/*把处理好的中间变量移回来*/
112                                           }
113                                    }
114                                  break;
115 
116                         case 'D':
117 
118                         case 'd':/*右*/
119                                  for(i=0;i<=3;i++)
120                                    {
121                                         for(j=0;j<=3;j++)
122                                           {
123                                                temp[j]=code[i][3-j];/*把一行数移到中间变量*/
124                                           }
125                                         temp[4]=0;
126                                         change += add();
127                                         for(j=0;j<=3;j++)
128                                           {
129                                                code[i][3-j]=temp[j];/*把处理好的中间变量移回来*/
130                                           }
131                                    }
132                                  break;
133                    }
134               gameover=1;
135               for(i=0;i<=3;i++)
136               for(j=0;j<=3;j++)
137               if(code[i][j]==0)
138               gameover=0;/*所有格子都填满则游戏结束*/
139         }
140     printf("Game over!n");
141     getch();
142 
143     return 0;
144 }
145 
146 void print(void)/*显示游戏界面*/
147 {
148     int i,j;
149     system("CLS");/*清屏*/
150     printf("2048n");
151     printf("W--UP A--LEFT S--DOWN D--RIGHT 0--EXITn");
152     printf("Score:%d Move:%dn",score,move);
153     printf("Made by lanshanxiaon");
154     printf("|-----------------------|n");/*显示横向分隔线*/
155     for(i=0;i<=3;i++)
156        {
157            for(j=0;j<=3;j++)
158               {
159                    if(code[i][j]==0)
160                      {
161                           printf("|     ");/*0显示空格*/
162                      }
163                    else
164                      {
165                           printf("|%5d",code[i][j]);/*显示数字和分隔线*/
166                      }
167               }
168            printf("|n|-----------------------|n");/*显示横向分隔线*/
169        }
170 }
171 
172 int add(void)/*对中间变量数组进行处理*/
173 {
174     int i;
175     int t=0;
176     int change=0;/*判断数组是否有改变,0不变,1变化*/
177     do
178      {
179           for(i=0;i<=3;i++)
180             {
181                  if(temp[i]==0)
182                   {
183                        if(temp[i]!=temp[i+1])
184                          change=1;/*当一个0后面不是0时数组改变*/
185                        temp[i]=temp[i+1];
186                        temp[i+1]=0;
187                   }
188             }/*去掉中间的0*/
189           t++;
190      }while(t<=3);/*重复多次*/
191     for(i=1;i<=3;i++)
192         {
193              if(temp[i]==temp[i-1])
194               {
195                    if(temp[i]!=0)
196                      {
197                           change=1;/*当两个非零相同的数相加时数组改变*/
198                           score=score+temp[i];/*加分*/
199                      }
200                    temp[i-1]=temp[i-1]*2;
201                    temp[i]=0;
202               }
203         }/*把两个相邻的相同的数加起来*/
204 
205     return change;
206 }

Get端:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Runtime.InteropServices;
using System.Windows.Interop;

namespace GetTest
{
    /// <summary>
    /// MainWindow.xaml 的交互逻辑
    /// </summary>
    public partial class MainWindow : Window
    {
        IntPtr hwnd;
        public MainWindow()
        {
            InitializeComponent();
            this.Title = "接受窗口";

            this.Loaded += new RoutedEventHandler(MainWindow_Loaded);
            this.Closed += new EventHandler(MainWindow_Closed);
        }

        void MainWindow_Loaded(object sender, RoutedEventArgs e)
        {
            //窗口加载完毕才可用,否则会报错。
            hwnd = new WindowInteropHelper(this).Handle;
            HwndSource source = HwndSource.FromHwnd(hwnd);
            if (source != null) source.AddHook(WndProc);
        }

        void MainWindow_Closed(object sender, EventArgs e)
        {
            try
            {
                HwndSource.FromHwnd(hwnd).RemoveHook(WndProc);
            }
            catch (Exception)
            {

                throw;
            }

        }

        const int WM_COPYDATA = 0x004A;//WM_COPYDATA消息的主要目的是允许在进程间传递只读数据。
        //Windows在通过WM_COPYDATA消息传递期间,不提供继承同步方式。
        //其中,WM_COPYDATA对应的十六进制数为0x004A
        public struct COPYDATASTRUCT
        {
            public IntPtr dwData;
            public int cData;
            [MarshalAs(UnmanagedType.LPStr)]
            public string lpData;
        }

        //wpf用此方法
        private IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
        {
            if (msg == WM_COPYDATA)
            {
                COPYDATASTRUCT cdata = new COPYDATASTRUCT();
                Type mytype = cdata.GetType();
                cdata = (COPYDATASTRUCT)Marshal.PtrToStructure(lParam, mytype);
                this.textBox1.Text = cdata.lpData;
            }
            return IntPtr.Zero;
        }

        //WinFrom用此方法
        /* protected override void DefWndProc(ref Message m)
        {
            switch (m.Msg)
            {
            case WM_COPYDATA:
                COPYDATASTRUCT cdata = new COPYDATASTRUCT();
                Type mytype = cdata.GetType();
                cdata = (COPYDATASTRUCT)m.GetLParam(mytype);
                this.textBox1.Text = cdata.lpData;
                break;
            default:
                base.DefWndProc(ref m);
                break;
            }
        } */
    }
}

数据结构概念

  • 在《Data Structures and Algorithm Analysis in C》(以下简称DSAAC)一书中并未提及数据结构的具体定义。

    与数据结构定义比较接近的我认为应该是在第3章:表、栈和队列中提及的抽象数据类型(Abstract Data Type,ADT),书中将抽象数据类型看作是一些操作的集合,并认为ADT中无需设计如何实现操作的集合,其可视为模块化设计的补充。

    并举例:表、集合、图和它们的操作一起可以看作是抽象数据类型

  • 在陈越老师主讲的《数据结构》(以下简称《数据结构》)中,陈越老师认为数据结构并没有统一的官方定义。

    但是陈老师通过对比各类数据结构相关数据所下定义提取了关键字。
    图片 1

通过图片可以看到关键字为“数据结构”和“算法”,可见数据结构是与算法密不可分的(看到这里的时候我只是觉得数据结构却是和算法结合的很紧密,但并没有明白数据机构到底是什么)。

紧接着陈老师通过举例:如何在书架上摆放图书,引入了

“解决问题方法的效率跟数据的组织方式有关”这一观点。

至此,我大概了解了陈老师所想表达的观点,即:

数据通过不同的算法进行组成成为有结构的数据,再通过不同算法对数据进行操作,结构化的数据与对数据的操作集共同形成了数据结构(自己总结的,如有不妥还请指出)

在陈老师的课中,还举例了设计打印函数PrintN并对循环及递归算法进行比较
图片 2

通过比较即可发现循环和递归算法实现时,数据量对于递归算法的效率影响是十分大的,并且在数据量达到1e7级别时,内存随即崩盘。

如果对于C语言有一定了解的话,可以知道:编译器是被分配一个默认大小的堆栈空间,一旦堆栈超过这个空间随即就会崩溃(虽然我们可以通过调整编译器默认空间来解决这一问题,但这个比较还反映了利用递归算法时造成的空间复杂度过高的问题)我们在如下代码中可以发现

void Print(int N){
if(N!=0){
Print(N-1);
printf("%dn",N);
 }
}

一旦使用此递归算法,意味着无论数据量多大,程序都会一路递归到N=0的情况,才会讲栈帧逐个Pop出去,这样带来的巨大问题就是堆栈占用量超出了编译器所拥有的默认空间,导致程序甚至编译器崩溃

陈老师由此导出了另一个结论:

解决问题方法的效率,跟空间的利用效率有关

紧接着陈老师利用clock()函数对不同算法计算多项式进行了比较
图片 3

并得出了另一个观点即:解决问题方法的效率,跟算法的巧妙程度有关

陈老师最后给出了什么是数据结构???这一问题的回答,即:

  • 数据对象在计算机中的组织方式

    • 逻辑结构

    • 物理存储结构

  • 数据对象必定与一系列加在其上的操作相关联

  • 完成这些操作所用的方法就是算法

 

Send端:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Runtime.InteropServices;

namespace SentTest
{
    /// <summary>
    /// MainWindow.xaml 的交互逻辑
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            this.Title = "发送窗口";
        }

        const int WM_COPYDATA = 0x004A;

        public struct COPYDATASTRUCT
        {
            public IntPtr dwData;
            public int cData;
            [MarshalAs(UnmanagedType.LPStr)]
            public string lpData;
        }

        [DllImport("User32.dll")]
        public static extern int SendMessage(int hwnd, int msg, int wParam, ref COPYDATASTRUCT IParam);
        [DllImport("User32.dll")]
        public static extern int FindWindow(string lpClassName, string lpWindowName);

        private void button1_Click(object sender, RoutedEventArgs e)
        {
            String strSent = "需要发送的信息";

            int WINDOW_HANDLE = FindWindow(null, "接收窗口");
            if (WINDOW_HANDLE != 0)
            {
                byte[] arr = System.Text.Encoding.Default.GetBytes(strSent);
                int len = arr.Length;
                COPYDATASTRUCT cdata;
                cdata.dwData = (IntPtr)100;
                cdata.lpData = strSent;
                cdata.cData = len + 1;
                SendMessage(WINDOW_HANDLE, WM_COPYDATA, 0, ref cdata);
            }
        }
    }
}

C语言实现(C-Support)

  • 《C Prime Plus》(以下简称《CPP》) 一书中在第14章:结构和其他数据形式对数据结构做了较为详细的C语言实现讲解。14章关键字为:struct , union , typedef。

  • 在讲解数据结构的基础概念时,《CPP》中利用了book.c及manybook.c两个渐进的例程来对数据结构进行具体的说明。其中,manybook.c的功能为录入library中书籍信息,并将其打印出来。笔者接下来也利用经过笔者注释的manybook.c程序进行相关概念的阐述

struct book{ //定义book结构
char title[MAXTITL];//定义结构第一个成员字符组title
char author[MAXAUTL];//定义结构第二个成员字符组author
float value;//定义结构第三个成员浮点变量value
};
  • 通过上述例程我们可知,该Book结构中包含了三个成员(member)或者叫做字段(field),定义一个结构有如下三个重要技巧:

    • 建立结构的格式或布局
    • 声明遵循该布局的变量(上述程序由于是节选自manybook.c并未声明)
    • 获取对一个结构变量各个部件的访问
  • 在manybook.c的主程序部分我们声明了相应的library变量

    struct book library[MAXBKS]; //定义结构变量

    并通过访问结构变量中的成员完成对图书的管理,如:

while(count < MAXBKS && gets(library[count].title)!=NULL&&library[count].title[0]!=''){ /*while循环条件分别为:1.当前输入数本册书小于书库最大可容纳书本册书
                     2.library[count].title当前值不为空
                     3。title首字符不为''*/
    printf("Now enter the author.n");
    gets(library[count].author);
    printf("Now enter the value.n");
    scanf("%f",&library[count++].value);
    while(getchar()!='n')
        continue;//遇上换行符时跳出while循环
    if(count < MAXBKS)
        printf("Enter the next title.n");
}

通过上述程序完成对书本信息的录入,值得关注的是:

gets(library[count].author);

这行代码,为:对于library结构变量中第(count+1)个变量中author成员的赋值。

  • 通过示例程序的演示,很好地了解了如何定义一个结构,以及结构中含有的成员,对于数据结构C语言的初步实现有了较好的了解。

2048小游戏代码在上面的View Code中,将加号展开就可以看到。

数据结构基础入门(Base of Data Sructures)

本文由澳门新葡亰手机版发布于编程,转载请注明出处:进程间通信,鱼龙混杂

上一篇:没有了 下一篇:修饰符的用法,NET开发资源大全
猜你喜欢
热门排行
精彩图文