找回密码
 加入
搜索
查看: 3951|回复: 6

[网络通信] 程序间传递数据的问题

  [复制链接]
发表于 2010-9-19 20:32:37 | 显示全部楼层 |阅读模式
发送端:
#include <winapi.au3>

GUICreate('Send')

GUIRegisterMsg(0x4A, '_Rec')

_Send()



While 1

        sleep(1000)

wend



Func _Send()

        $hwnd = WinGetHandle('Rec')

        $message = '发送端的信息,发送OK'



        $struct = DllStructCreate('wchar var1[1000]')

        DllStructSetData($struct, 1, $message)

        $pStruct = DllStructGetPtr($struct)



        $struct2 = DllStructCreate('dword;dword;ptr')

        DllStructSetData($struct2, 1, 0)

        DllStructSetData($struct2, 2, 1000)

        DllStructSetData($struct2, 3, $pStruct)

        $pStruct2 = DllStructGetPtr($struct2)



        _SendMessage($hwnd, 0x4A, 0, $pStruct2)



Endfunc   ;==>_Send





Func _Rec($hwnd, $iMsg, $iwParam, $ilParam)



        $a1 = DllStructCreate('dword var1;dword var2;ptr var3', $ilParam)

        $a2 = DllStructGetData($a1, 3)

        $a3 = DllStructCreate('wchar var1[1000]', $a2)

        $a4 = DllStructGetData($a3, 1)



        MsgBox(0, '发送端收到', $a4)

EndFunc   ;==>_Rec
接收端:
#include <winapi.au3>


GUICreate('Rec')

GUIRegisterMsg(0x4A, '_Rec')

sleep(3000)

_send()

While 1

        Sleep(1000)

WEnd



Func _send()

        $hWnd = WinGetHandle('Send')

        $message = '接收端的信息,发送ok'

        $struct = DllStructCreate('wchar var1[1000]')

        DllStructSetData($struct, 1, $message)

        $pStruct = DllStructGetPtr($struct)



        $struct2 = DllStructCreate('dword;dword;ptr')

        DllStructSetData($struct2, 1, 0)

        DllStructSetData($struct2, 2, 1000)

        DllStructSetData($struct2, 3, $pStruct)

        $pStruct2 = DllStructGetPtr($struct2)



        _SendMessage($hWnd, 0x4A, 0, $pStruct2)



Endfunc   ;==>_send



Func _Rec($hWnd, $iMsg, $iwParam, $ilParam)



        $a1 = DllStructCreate('dword var1;dword var2;ptr var3', $ilParam)

        $a2 = DllStructGetData($a1, 3)

        $a3 = DllStructCreate('wchar var1[1000]', $a2)

        $a4 = DllStructGetData($a3, 1)



        MsgBox(0, '接收端收到', $a4)

EndFunc   ;==>_Rec
上面的这个例子程序是我从论坛上搜到的,看了看例子只是两个程序间传递字符串数据,现在我需要的是send端给rec端发送的是一个数组,能修改利用这个例子吗?望高手出手,学习了
发表于 2010-9-19 21:22:27 | 显示全部楼层
_ArraytoString()
发表于 2010-9-20 09:48:07 | 显示全部楼层
不错学习了。。
 楼主| 发表于 2010-9-20 09:49:00 | 显示全部楼层
谢谢楼上解答
但是转换成字符串的办法不能解决二维数组的传递
是不是上面的 DllStructCreate函数里的参数改一下就可以传递数组了呢?对于数组数据不知道怎么改成相应的参数,
发表于 2010-9-20 14:30:21 | 显示全部楼层
本帖最后由 C.L 于 2010-9-20 14:31 编辑

回复 4# manlty

1楼的代码好熟悉

二维数组转换成字符串,我以前也写过转换的代码:

#include<array.au3>
Dim $a[2][3] = [[1,2,3],[3,4,5]]
$sArray = _Array2DToString ($a)
MsgBox (0,'二维数组二进制数据',$sArray)
$array = _StringToArray2D ($sArray)
_ArrayDisplay ($array,'还原二维数组')

Func _Array2DToString ($array)
        Local $array1,$arrya2,$out = ""
        $array1 = UBound($array,1)
        $array2 = UBound($array,2)
        $out = $array1&"|"&$array2
        For $i=0 To $array1-1
                For $j=0 To $array2-1
                        $out &=  "|" & $array[$i][$j] 
                Next
        Next
        Return StringToBinary ($out,4)
EndFunc

Func _StringToArray2D($binData)
        Local $temp
        $string = BinaryToString ($binData,4)
        $temp = StringSplit ($string,"|")
        Local $array2d[$temp[1]][$temp[2]]
        $k = 3
        For $i=0 To $temp[1]-1
                For $j=0 To $temp[2]-1
                        $array2d [$i][$j] = $temp [$k]
                        $k += 1
                Next
        Next
        Return $array2d
EndFunc

评分

参与人数 2金钱 +60 收起 理由
zps26 + 30
afan + 30

查看全部评分

发表于 2010-9-20 16:46:47 | 显示全部楼层
如果数组中全是数值的话,可以将数组转化为数据结构,这将大大减少存储空间。

比如,一个2维数组如下,里面全是介于0x0000~0xFFFF之间的数字(即每个数值占用空间2字节)。
[0][0] = 1
[0][1] = 128
[1][0] = 1024
[1][1] = 65535
... ...
[n][0] = x

那么可以转换为如下数据结构:
dword UBound1;dword UBound2;ushort 0_1st;ushort 0_2nd;ushort 1_1st;ushort 1_2nd;... ushort n_1st;ushort n_2nd

dword UBound1是处于1维中的元素数量,即UBound($aArray, 1)。
dword UBound2是处于2维中的元素数量,即UBound($aArray, 2)。

ushort 0_1st即是[0][0]。
ushort 0_2nd - [0][1]。
ushort 1_1st - [1][0]。
ushort 1_2nd - [1][1]。
... ...
ushort n_1st - [n][0]。
ushort n_2nd - [n][1]。

如果一个2维数组的1维数量是2,2维元素数量同是2,且数值位于0~65535之间,转换为数据结构之后,它所占用的空间长度是:
8 + UBound($aArray, 1) * UBound($aArray, 2) * 2,比起转换为字符串,占用空间很明显要少很多。

因为转换为字符串,上面的数组最少要17字节,因为还要有一个不同于数组性质的分隔符(上面数组的性质就是全是2字节数字),好吧,用一个逗号“,”作为分隔符,转为字符串之后将是“1,128,1024,65535”。这个字符串的长度是16字节(1个ANSI字符占用空间1字节),另外还要在加1个NULL字符(Chr(0))用于结尾,因为还要说明维数及元素数量,所以占用到的空间不止这17字节。

如果数字位于0x00000000~0xFFFFFFFF之间,转为数据结构之后,长度应该是8 + UBound($aArray, 1) * UBound($aArray, 2) * 4,因为一个dword占4字节,同样的结构中的ushort也应该改成dword或者long。

以上只限于数组中全是数字的情况。
如果一个2维数组既包含数字,又包含字符串,那么同样可以全部转换为字符串,但占用长度同会大大增加。转为数据结构,可以如下:
dword UBound1;dword UBound2;ptr 0_1st;ptr 0_2nd;ptr 1_1st;ptr 1_2nd

同样的dword UBound1;dword UBound2用于说明维数及数量。
ptr 0_1st 是个指针,所指向的地址中包含数组[0][0]的值,ptr 0_2nd同是,指向数组[0][1]。

这个结构占用的长度是 8 + UBound($aArray, 1) * UBound($aArray, 2) * 4 (ptr占用4字节)。

另外,必须要考虑到接收端接收到数据之后,可能将会对数组进行删减、插入或排序操作,那么使用如上的结构将会存在效率问题。因为如果要删除数组中的[1][0]([1][0]删除的同时,[1][1]同会被删除),必须将[1]之后的元素往前提升,[1]之前的数据不变,进行插入操作会更加费时。

使用链表将会弥补这丢失的效率,并且会更加符合逻辑。
ptr Next;ptr 1st;ptr 2nd。

1st表示当前数组索引中的[0](处于2维中)号元素的位置。
增加了一个ptr Next,这个成员用于说明下一个数组元素在内存中的什么地方,即指向了下一个数组元素。如果要在数组的[0]与[1]之间插入一个元素,那么只需要修改[0]中的ptr Next的值就可以了,使其指向要插入的元素,插入的元素中的ptr Next指向原本的[1],其他数据不变。
如果要删除[2],直接修改[1]中的ptr Next,使其指向[3]。
删除最后一个,修改UBound($aArray) - 2中Next的值,改为0,表示这是最后一个元素。

这是一个单向链表,在查找数据时,只能从前往后查。如果对查找的效率有很大要求,可以定义一个双向链表:
ptr Prev;ptr Next;ptr 1st;ptr 2nd。
ptr Prev表示上一个元素的位置。
第一个元素中的Prev指向最后一个元素,最后一个元素的Next指向第一个元素,形成一个圈。

以上。
在AU3中,数据结构的应用貌似不太广泛,一切算法都会基于数据结构,熟用数据结构将会带来节省资源和提升效率的结果。

评分

参与人数 3威望 +10 金钱 +130 收起 理由
zps26 + 30
afan + 50 满满滴学问,可惜看不懂…
水木子 + 10 + 50 辛苦啦!

查看全部评分

 楼主| 发表于 2010-9-20 20:08:25 | 显示全部楼层
太高深了,数据结构不好理解啊
您需要登录后才可以回帖 登录 | 加入

本版积分规则

QQ|手机版|小黑屋|AUTOIT CN ( 鲁ICP备19019924号-1 )谷歌 百度

GMT+8, 2024-6-2 06:16 , Processed in 0.087197 second(s), 29 queries .

Powered by Discuz! X3.5 Licensed

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表