leon460 发表于 2011-11-19 23:11:19

子进程如何返回值给主进程

下面有些叫法可能不是那么准确,但应该能说明意思
描述:我就把开始的叫主函数,通过主函数传递一个参数给子进程,子进程通过参数计算出一个结果,然后再返回给主函数。主函数能传递若干个参数给对应的子进程。子进程完成计算后,能立即返回计算值,且主函数能理解接受。他们之间相互不影响。
以上需做到互不影响。
举个例子吧:主函数连续传十个参数1-10给子进程1-10,子进程接受到后,返回的值为参数乘以10,并返回,主函数能立即处理返回值,msgbox(0,第一个子进程,第一个子进程返回的值)-------,相互间不能影响。

我曾经尝试用 CoProc_CoProcReciver效果不好,有大哥知道的以上解决的,请给我个思路和简单代码,谢谢。

yeqing880 发表于 2011-11-20 11:31:28

以前我是用ini的方法 让子进程的返回值写入INI文件。。主进程读取INI就可以了

后来用的是 “程序间的参数传递及通讯”

http://www.autoitx.com/forum.php?mod=viewthread&tid=5425&highlight=%B3%CC%D0%F2%BC%E4

bdancerlc 发表于 2011-11-20 18:33:39

ini 配置文件经常用,..

曼菲士 发表于 2011-12-9 12:02:23

回复 2# yeqing880


    ;===============================================================================
;
; Description:      Register Reciver Function
; Parameter(s):   $sFunction - Optional, Function name to Register.
;                                                                Omit to Disable/Unregister
; Requirement(s):   3.2.4.9
; Return Value(s):On Success - Returns True
;                   On Failure - Returns False and Set
;                                                                                                @error to:        1 - Unable to create Reciver Window
;                                                                                                                        2 - Unable to (Un)Register WM_COPYDATA or WM_USER+0x64
; Author(s):      Florian 'Piccaso' Fida
; Note(s):                        If the process doesent have a Window it will be created
;                                        The Reciver Function must accept 1 Parameter
;
;===============================================================================
Func _CoProcReciver($sFunction = Default)
        Local $sHandlerFuction = "__CoProcReciverHandler", $hWnd, $aTmp
        If IsKeyword($sFunction) Then $sFunction = ""
        $hWnd = _ProcessGetWinList(@AutoItPID, "", 16 + 2)
        If Not IsHWnd($hWnd) Then
                $hWnd = GUICreate("CoProcEventReciver")
                If @error Then Return SetError(1, 0, False)
        EndIf
        If $sFunction = "" Or IsKeyword($sFunction) Then $sHandlerFuction = ""
        If Not GUIRegisterMsg(0x4A, $sHandlerFuction) Then Return SetError(2, 0, False) ; WM_COPYDATA
        If Not GUIRegisterMsg(0x400 + 0x64, $sHandlerFuction) Then Return SetError(2, 0, False) ; WM_USER+0x64
        $gs_CoProcReciverFunction = $sFunction
        Return True
EndFunc   ;==>_CoProcReciver
Func __CoProcReciverHandler($hWnd, $iMsg, $WParam, $LParam)
        If $iMsg = 0x4A Then ; WM_COPYDATA
                Local $COPYDATA, $MyData
                $COPYDATA = DllStructCreate("ptr;dword;ptr", $LParam)
                $MyData = DllStructCreate("char[" & DllStructGetData($COPYDATA, 2) & "]", DllStructGetData($COPYDATA, 3))
                $gv_CoProcReviverParameter = DllStructGetData($MyData, 1)
                Return 256
        ElseIf $iMsg = 0x400 + 0x64 Then ; WM_USER+0x64
                If $gv_CoProcReviverParameter Then
                        Call($gs_CoProcReciverFunction, $gv_CoProcReviverParameter)
                        If @error And @Compiled = 0 Then MsgBox(16, "CoProc Error", "Unable to Call: " & $gs_CoProcReciverFunction)
                        $gv_CoProcReviverParameter = 0
                        Return 0
                EndIf
        EndIf
EndFunc   ;==>__CoProcReciverHandler

;===============================================================================
;
; Description:      Send a Message to a CoProcess
; Parameter(s):   $vProcess - Name or PID of Process
;                                        $vParameter - Parameter to pass
;                                        $iTimeout - Optional, Defaults to 500 (msec)
;                                        $fAbortIfHung - Optional, Default is True
; Requirement(s):   3.2.4.9
; Return Value(s):On Success - Returns True
;                   On Failure - Returns False and Set
;                                                                                                @error to:        1 - Process not found
;                                                                                                                        2 - Window not found
;                                                                                                                        3 - Timeout/Busy/Hung
;                                                                                                                        4 - PostMessage Falied
; Author(s):      Florian 'Piccaso' Fida
; Note(s):
;
;==========================================================================
Func _CoProcSend($vProcess, $vParameter, $iTimeout = 500, $fAbortIfHung = True)
        Local $iPid, $hWndTarget, $MyData, $aTmp, $COPYDATA, $iFuFlags
        $iPid = ProcessExists($vProcess)
        If Not $iPid Then Return SetError(1, 0, False) ; Process not Found
        $hWndTarget = _ProcessGetWinList($vProcess, "", 16 + 2)
        If @error Or (Not $hWndTarget) Then Return SetError(2, 0, False) ; Window not found
        $MyData = DllStructCreate("char[" & StringLen($vParameter) + 1 & "]")
        $COPYDATA = DllStructCreate("ptr;dword;ptr")
        DllStructSetData($MyData, 1, $vParameter)
        DllStructSetData($COPYDATA, 1, 1)
        DllStructSetData($COPYDATA, 2, DllStructGetSize($MyData))
        DllStructSetData($COPYDATA, 3, DllStructGetPtr($MyData))
        If $fAbortIfHung Then
                $iFuFlags = 0x2 ; SMTO_ABORTIFHUNG
        Else
                $iFuFlags = 0x0 ; SMTO_NORMAL
        EndIf
        $aTmp = DllCall("user32.dll", "int", "SendMessageTimeout", "hwnd", $hWndTarget, "int", 0x4A _; WM_COPYDATA
                        , "int", 0, "ptr", DllStructGetPtr($COPYDATA), "int", $iFuFlags, "int", $iTimeout, "long_ptr", 0)
        If @error Then Return SetError(3, 0, False) ; SendMessageTimeout Failed
        If Not $aTmp Then Return SetError(3, 0, False) ; SendMessageTimeout Failed
        $aTmp = DllCall("user32.dll", "int", "PostMessage", "hwnd", $hWndTarget, "int", 0x400 + 0x64, "int", 0, "int", 0)
        If @error Then Return SetError(4, 0, False)
        If Not $aTmp Then Return SetError(4, 0, False)
        Return True
EndFunc   ;==>_CoProcSend

看了一下CoProc.au3里面的代码,也是用WM_COPYDATA这个东东,如果楼主遇到这个问题,那应该是WM_COPYDATA的问题。

曼菲士 发表于 2011-12-9 12:06:41

回复 1# leon460


还未到达楼主的级别,不知楼主说的是信息接收延迟问题还是信息冲突问题?

如果是信息冲突问题,楼主是否考虑改进信息分类?例如A子进程发回的信息以 A 开头,B的以B开头好区分是哪个进程发回的信息。

andersonljw 发表于 2012-1-8 09:20:18

二楼好。。。。。。。
页: [1]
查看完整版本: 子进程如何返回值给主进程