【高级】AutoHotkey调用com对象时如果返回两个(多个)值该如何处理?

这是一个在autohotkey领域的技术突破。

一、函数返回值的情况

通常我写一个函数会通过return返回一个值:

例如:写一个加法。

sum(a,b)
{
    Return,a+b
}

如果有多个返回值,我们一般有两种选择:

(1)通过对象(数组)

例如:函数同时返回加法和减法的值

arr:=sum(3,1)
MsgBox,% arr[1]
Return
sum(a,b)
{
    Array:=[]
    Array[1]:=a+b
    Array[2]:=a-b
    Return,Array
}

(2)通过byref

例如:写一个交换函数

a:=3
b:=1
Swap(a,b)
MsgBox,% a
Return
Swap(ByRef Left, ByRef Right)
{
    temp := Left
    Left := Right
    Right := temp
}

二、com对象返回值的情况

单个返回值的时候,跟函数的调用是一样的,直接写就行了,下面的代码来自中文社区QQ群random

这是一个调用opencv打开文件的代码,原文链接:AHK调用opencv(四)播放视频文件

这是一个完美运行的代码:

#NoEnv
SendMode Input
SetWorkingDir %A_ScriptDir%
hOpencv := DllCall("LoadLibrary", "str", "opencv_world455.dll", "ptr")
hOpencvCom := DllCall("LoadLibrary", "str", "autoit_opencv_com455.dll", "ptr")
DllCall("autoit_opencv_com455.dll\DllInstall", "int", 1, "wstr", A_IsAdmin = 0 ? "user" : "", "cdecl")
cv  := ComObjCreate("OpenCV.cv")
cap := ComObjCreate("OpenCV.cv.VideoCapture")
frame := ComObjCreate("OpenCV.cv.MAT") 
cap.open("test001.avi")
istrue := cap.isOpened() ;返回布尔值,成功打开时值为true,反之为false
;MsgBox, % istrue
While istrue{
    ret := cap.read(frame)
    img_gray := cv.cvtColor(frame, CV_COLOR_BGR2GRAY := 6)
    cv.imshow("Image", img_gray)
}

在正确运行之前,社区多位大佬进行了测试和研究。

关键点就是这行代码:

ret := cap.read(frame)

这个是opencv中VideoCapture类的成员方法:

c++调用格式这个结构:

virtual bool cv::VideoCapture::read	(	OutputArray 	image	)	

python调用这个结构:

cv.VideoCapture.read(	[, image]	) ->	retval, image

按理说,ahk调用应该跟python差不多,那就分析一下python如何调用的:

参数
    无
返回值
    ret         布尔型 (True 或者False),代表有没有读取到图片
    frame    表示截取到的一帧的图片的数据,是个三维数组
实例

 ret, frame = cap.read()  #读取一帧图像
 # ret 读取了数据就返回True,没有读取数据(已到尾部)就返回False
# frame 返回读取的视频数据 ——  一帧数据是一个三维数组

其中ret是布尔值,如果读取帧是正确的则返回True,如果文件读取到结尾,它的返回值就为False。frame就是每一帧的图像,是个三维矩阵。

到这里卡住了,AutoHotkey没有这样直接返回两个值的方式!!!!!!!!!!!

经过不懈努力,最后由Tebayaki破解:最后调用的是c++的调用结构:

先用ComObjCreate把frame的结构构造出来一个多维数组:

frame := ComObjCreate("OpenCV.cv.MAT") 

然后直接按照c++的方式调用即可:

ret := cap.read(frame)

三、总结

遇到这种多个返回值的com对象,大凡都是通过这种方式进行返回相关的值,究其原因可能是ahk不怎么注意参数类型导致大家什么都敢往方法里传,read需要的参数就是一个mat类的对象,我们就按它的要求创建一个传进去就行了,可能要调用的com方法不熟悉也有关系。

总之这个问题解决了,这是一个小小的突破,对于中文社区确实一个大大的进步,对于ahk国内相对较晚接触,中文社区在各个方面一直在追赶英文论坛,虽然硬件上已经远超英文论坛,技术上优先突破,这个可能还是第一次,社区未来一定越来越多的突破从我们这里开始,加油!

 

给TA捐赠
共{{data.count}}人
人已捐赠
其他教程

AHK调用opencv(四)播放视频文件

2022-2-14 22:50:36

教程

AutoHotkey数据类型详解

2022-2-15 16:31:55

4 条回复 A文章作者 M管理员
  1. 不想说什么

    多谢分享,希望中文ahk能形成咱自己的生态

  2. OHHHahk

    中文ahk

  3. Nathen

    感谢分享

  4. rastar

    试试一下

个人中心
购物车
优惠劵
有新私信 私信列表
搜索