一聚教程网:一个值得你收藏的教程网站

热门教程

C#调用返回值为字符串的dll api,调试模式下崩溃

时间:2022-06-25 08:18:09 编辑:袖梨 来源:一聚教程网

件的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)

只有在验证码识别错误时才运行这个方法,恶意提交将会受到惩罚

热门栏目