件的api傳回值都是字串類型,考慮vs2012中C#的託管指標調試可能有改動.所以將傳回值類型修改為
IntPtr,在調用api後,將傳回值用Marshal.PtrToStringAnsi轉為字串,解決方案繁瑣了點,不知有無更
好的方案了.
C#代碼
| 代碼如下 |
複製代碼 |
|
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Runtime.InteropServices;
using System.IO;
using System.Collections;
namespace QQ超人打碼範例
{
class Program
{
[DllImport("dc.dll")]
private static extern IntPtr GetUserInfo(string user, string pass);
[DllImport("dc.dll")]
private static extern IntPtr RecByte_A(byte[] img, int imgLen, string user, string
pass, string softId);
[DllImport("dc.dll")]
private static extern IntPtr RecYZM_A(string imgPath, string user, string pass,
string softId);
[DllImport("dc.dll")]
private static extern void ReportError(string user, string worker);
static void Main(string[] args)
{
//帳號配置
string user = "user";
string pass = "pass";
string softId = "0";
//查詢剩餘點數
IntPtr info = GetUserInfo(user, pass);
Console.WriteLine("剩餘點數{0}",Marshal.PtrToStringAnsi(info));
//按圖片資料識別驗證碼
FileStream fs = new FileStream("code.jpg", FileMode.Open,FileAccess.Read);
byte[] bFile = new byte[fs.Length];
BinaryReader r = new BinaryReader(fs);
bFile=r.ReadBytes((int)fs.Length);
r.Close();
r=null;
fs.Close();
Console.WriteLine("RecByte_A驗證碼遠程識別中");
IntPtr result = RecByte_A(bFile, bFile.Length, user, pass, softId);
Console.WriteLine("返回的驗證碼識別結果:{0}", Marshal.PtrToStringAnsi(result));
//按圖片路徑識別驗證碼
Console.WriteLine("RecYZM_A驗證碼遠程識別中");
IntPtr result2 = RecYZM_A("code.jpg", user, pass, softId);
Console.WriteLine("返回的驗證碼識別結果:{0}", Marshal.PtrToStringAnsi
(result2));
/*
//報告錯誤 只有在確定驗證碼錯誤的情況下才調用該函數
string worker = "F36B1D3A30474A75B497D82FC6342CFC";
ReportError(user,worker);
*/
Console.Read();
}
}
} |
有個類似的例子就是python下的調用,python調用的時候,也是返回託管的字串指標,需要用
ctypes.string_at將指標轉換為字串
| 代碼如下 |
複製代碼 |
# -*- coding:utf-8 -*-
import ctypes
import sys
from os.path import join, dirname, abspath, exists
dll = ctypes.windll.LoadLibrary(join(dirname(__file__),'dc.dll'))
class dcVerCode:
#user QQ超人打碼帳號
#pwd QQ超人打碼密碼
#softId 軟體ID 預設為0,作者務必提交softId,已保證分成
def __init__(self,user,pwd,softId="0"):
self.user = user
self.pwd = pwd
self.softId = softId
#擷取帳號剩餘點數
def getUserInfo(self):
p = dll.GetUserInfo(self.user,self.pwd)
if p:
return ctypes.string_at(p,-1)
return ''
def parseResult(self,result):
list = result.split('|')
if len(list)==3:
return (list[0],list[2])
return (NULL,NULL)
#recByte 根據圖片位元據識別驗證碼,返回驗證碼,打碼工人編號
#buffer 圖片位元據
def recByte(self,buffer):
p = dll.RecByte_A(buffer,len(buffer),self.user,self.pwd,self.softId)
if p:
str = ctypes.string_at(p,-1)
return self.parseResult(str)
return ''
#recYZM 根據驗證碼路徑識別,返回驗證碼,打碼工人編號
#path 圖片路徑
def recYZM(self,path):
p = dll.RecYZM_A(path,self.user,self.pwd,self.softId)
if p:
str = ctypes.string_at(p,-1)
return self.parseResult(str)
return ''
#reportErr 提交識別錯誤驗證碼
#worker 打碼工人編號
def reportErr(self,worker):
dll.ReportError(self.user,worker)
if __name__ == '__main__':
client = dcVerCode("user","pass","0");
img = open('c:\123.jpg','rb')
buffer = img.read()
img.close()
print (client.getUserInfo())
yzm,worker = client.recByte(buffer)
print(yzm,worker)
yzm,worker = client.recYZM("c:\123.jpg")
print ( yzm,worker )
#client.reportErr(worker) |
只有在驗證碼識別錯誤時才運行這個方法,惡意提交將會受到懲罰