manlty 发表于 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')

      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', $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')

      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', $a2)

      $a4 = DllStructGetData($a3, 1)



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

EndFunc   ;==>_Rec上面的这个例子程序是我从论坛上搜到的,看了看例子只是两个程序间传递字符串数据,现在我需要的是send端给rec端发送的是一个数组,能修改利用这个例子吗?望高手出手,学习了

republican 发表于 2010-9-19 21:22:27

_ArraytoString()

tianji028 发表于 2010-9-20 09:48:07

不错学习了。。

manlty 发表于 2010-9-20 09:49:00

谢谢楼上解答
但是转换成字符串的办法不能解决二维数组的传递
是不是上面的 DllStructCreate函数里的参数改一下就可以传递数组了呢?对于数组数据不知道怎么改成相应的参数,

C.L 发表于 2010-9-20 14:30:21

本帖最后由 C.L 于 2010-9-20 14:31 编辑

回复 4# manlty

1楼的代码好熟悉

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

#include<array.au3>
Dim $a = [,]
$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][$temp]
      $k = 3
      For $i=0 To $temp-1
                For $j=0 To $temp-1
                        $array2d [$i][$j] = $temp [$k]
                        $k += 1
                Next
      Next
      Return $array2d
EndFunc

pusofalse 发表于 2010-9-20 16:46:47

如果数组中全是数值的话,可以将数组转化为数据结构,这将大大减少存储空间。

比如,一个2维数组如下,里面全是介于0x0000~0xFFFF之间的数字(即每个数值占用空间2字节)。
= 1
= 128
= 1024
= 65535
... ...
= 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即是。
ushort 0_2nd - 。
ushort 1_1st - 。
ushort 1_2nd - 。
... ...
ushort n_1st - 。
ushort n_2nd - 。

如果一个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 是个指针,所指向的地址中包含数组的值,ptr 0_2nd同是,指向数组。

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

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

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

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

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

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

manlty 发表于 2010-9-20 20:08:25

太高深了,数据结构不好理解啊
页: [1]
查看完整版本: 程序间传递数据的问题