[AHK]调用TradeX.dll获取五档行情

版权声明:本文为博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/liuyukuan/article/details/91323762

私人定制开发服务,请加我微信 sunwind1576157。

 

AutoHotkey调用dll都是高级人的应用,数组、结构体、指针、指针数组的传参真挺难。

一直对numput 、numget心生敬畏,终于花了1个月啃了这块骨头。

不说了,赶紧上车,无图无真相!

 

查询【000001】【000012】【600050】3只股票的5档行情

#NoEnv 
;sunwind
;2019年6月8日
;功能:调用TradeX.dll获取五档行情
;感谢:ThinkAI、彪悍的小玄、爱尔兰之狐 的帮助。
;运行环境:兼容AutoHotkey A32 U32
;操作系统:Windows10 64位

dll:=A_ScriptDir . "\TradeX.dll"
Global g_dllName:="TradeX"
Global g_pszResult , g_pszErrInfo , g_nShortCount

/*
g_pszResult - 此 API 执行返回后,Result内保存了返回的查询数据, 形式为表格数据, 行数据之间通过\n 字符分割,列数据之间通过\t 分隔。 一般要分配 1024*1024 字节的空间。出错时为空字符串
*/
VarSetCapacity(g_pszResult, 1048576)

/*g_pszErrInfo - 此 API 执行返回后,如果出错,保存了错误信息说明。一般要分配 256 字节的空间。没出错时为空字符串。
*/
VarSetCapacity(g_pszErrInfo, 256)  ;256字节 
VarSetCapacity(g_nShortCount, 4)  ;4字节


caption := "加载DLL"
;当需要重复调用一个 DLL 时, 预先明确装载它可以显著提高执行效率
hModule:=DllCall("LoadLibrary", "str",dll, "Ptr")


caption := "连接普通行情服务器"
host:="59.173.18.140",port:=7709
;~ host:="119.147.212.81",port:=7709
;  1 :               招商证券深圳行情    119.147.212.81:7709
;  2 :             华泰证券(南京电信)    221.231.141.60:7709
;  3 :             华泰证券(上海电信)    101.227.73.20:7709
;  4 :           华泰证券(上海电信二)    101.227.77.254:7709
;  5 :             华泰证券(深圳电信)    14.215.128.18:7709
;  6 :             华泰证券(武汉电信)    59.173.18.140:7709
;  7 :             华泰证券(天津联通)    60.28.23.80:7709
;  8 :             华泰证券(沈阳联通)    218.60.29.136:7709
;  9 :             华泰证券(南京联通)    122.192.35.44:7709
; 10 :             华泰证券(南京联通)    122.192.35.44:7709

aResult:=DllCall("TradeX\TdxHq_Connect", "Astr",host,"Short",port,"str",g_pszResult,"str",g_pszErrInfo,"int")
if(ErrorLevel=-2)
	m(0, caption, "TdxHq_Connect" . "`r`n" . "返回值类型或某个指定的参数类型无效. ")
;~ if(ErrorLevel=0)
	;~ m(0, caption, "TdxHq_Disconnect"  "`r`n"  "开始测试")

a:=StrGet(&g_pszResult, "cp0")
b:=StrGet(&g_pszErrInfo, "cp0")
m(0, caption,a "`r`n" b "`r`n")


caption := "获取5档行情"

xMarket:= [0,0,1]
arr:=["000001","000012","600050"]

Count:=arr.MaxIndex()
NumPut(Count,&g_nShortCount,,"Char")

VarSetCapacity(zqdmStr,Count*14)
VarSetCapacity(zqdmPtr,Count* A_PtrSize)

arrPushStruct(arr,zqdmStr,zqdmPtr)

ret := DllCall("TradeX\TdxHq_GetSecurityQuotes", "ptr", &xMarket, "ptr", &zqdmPtr, "ptr",&g_nShortCount, "str", g_pszResult, "str", g_pszErrInfo)

a:=StrGet(&g_pszResult, "cp0")
b:=StrGet(&g_pszErrInfo, "cp0")

m(0, caption,a "`r`n" b "`r`n")


caption:= "断开连接"
aResult:=DllCall("TradeX\TdxHq_Disconnect")
if(ErrorLevel=-2)
	m(0, caption, "TdxHq_Disconnect"  "`r`n"  "返回值类型或某个指定的参数类型无效. ")
if(ErrorLevel=0)
	m(0, caption, "TdxHq_Disconnect"  "`r`n"  "结束测试")
	
DllCall("FreeLibrary", "Ptr", hModule)  ; 为了释放内存, 在使用 DLL 后需要进行卸载.
return

;功能:把数组元素的地址转存到一个结构体中。
;困难:
;1.要适配的dll只会按cp0解析地址,如果用AutoHotkeyU32默认地址是按cp1200存储地址。
;2.用AutoHotkeyU32 利用arr.GetAddress(A_Index)获取数组地址,默认会是CP1200编码,要适配的dll无法解码
;

;解决:
;1.先把arr数组的每项zqdm转存到zqdmStr结构体中,方便自己获取地址(不用arr.GetAddress)。
;2.再将每个zqdmStr的地址 存到 zqdmPtr结构体中。
arrPushStruct(arr,ByRef zqdmStr,ByRef zqdmPtr)
{
	bytes_per_char := A_IsUnicode ? 2 : 1
	SizeInBytes := (StrLen(arr[1]) + 1) * bytes_per_char
	Addr:=&zqdmPtr
	For Each, v In arr
	{
		elementAdr:=(&zqdmStr)+SizeInBytes*(A_Index-1) ;遍历数组中每个元素的地址
		strput(arr[A_Index],elementAdr,"cp0")	;强制以cp0转存,以适配特定dll。先把arr数组转存到zqdmStr结构体
		Addr :=NumPut(elementAdr,Addr+0,"Ptr")	;NumPut会自动更新addr为下一个元素的地址
		;~ 以二进制格式把数字存储到指定地址+偏移的位置.
		;~ NumPut(Number, VarOrAddress [, Offset := 0][, Type := "UPtr"])
	}
}


;封装msgbox为函数,默认 5秒自动关闭弹出的对话框
m(Options, Title, Text, Timeout=5)
{
   MsgBox, % Options,% Title, % Text, % Timeout
}

其它语言示例

 

 

autoit3的示例: 

;dim $req[2][2]
;
;$req[0][0] = 0
;$req[0][1] = "000001"
;
;$req[1][0] = 1
;$req[1][1] = "600300"
;

Func TdxHq_GetSecurityQuotes($req, ByRef $result, ByRef $errinfo)

   If Not IsArray($req) Or UBound($req, 0) <> 2 Then
	  $errinfo = "参数错误! $req不是数组或者数组维度不是2"
	  Return False
   EndIf

   Local $row = UBound($req, 1);
   Local $col = UBound($req, 2);

   If $row > 80 Then
	  $errinfo = "单次请求股票数太多! 最大数目80"
	  Return False
   EndIf

   If $col <> 2 Then
	  $errinfo = "数组元素应该包含: 市场代码和股票代码"
	  Return False
   EndIf

   Local $sField = ""
   For $k=0 to $row - 1
	  $sField &= "char[12];"
   Next

   Local $tagStruct = "struct;byte vecMarket[" & $row & "]; int_ptr vecZqdmPtr[" & $row & "]; " & $sField & "endstruct"
   Local $tStruct = DllStructCreate($tagStruct)

   If @error Then
        $errinfo = @error
        Return False
   EndIf

   For $i=0 to $row - 1

	  DllStructSetData($tStruct, 1, $req[$i][0], $i+1)
	  If @error Then
        $errinfo = @error
        Return False
	  EndIf

	  DllStructSetData($tStruct, 3 + $i, $req[$i][1])
	  If @error Then
        $errinfo = @error
        Return False
	  EndIf

	  DllStructSetData($tStruct, 2, DllStructGetPtr($tStruct, 3 + $i), $i+1)
	  If @error Then
        $errinfo = @error
        Return False
	  EndIf
   Next

   DllStructSetData($g_nShortCount, 1, $row)

   Local $aResult = DllCall($g_dllName, "boolean", "TdxHq_GetSecurityQuotes", _
	                           "ptr", DllStructGetPtr($tStruct, 1), _
							   "ptr", DllStructGetPtr($tStruct, 2), _
							   "ptr", DllStructGetPtr($g_nShortCount), _
							   "ptr", DllStructGetPtr($g_pszResult), _
							   "ptr", DllStructGetPtr($g_pszErrInfo))
   If @error Then
        $errinfo = @error
        Return False
   EndIf

   If $aResult[0] == 0 Then
	  $errinfo = DllStructGetData($g_pszErrInfo, 1)
   Else
	  $count = DllStructGetData($g_nShortCount, 1)
	  $result = DllStructGetData($g_pszResult, 1)
   EndIf

   $tStruct = 0

   Return $aResult[0]
EndFunc

 

没有更多推荐了,返回首页