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

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

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

时间: 2024-08-02 16:04:21

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

JAVA怎么调用返回多个Pchar的 dll

问题描述 functionCallA(constaddress:PChar;constsname:PChar;sin:PChar;sout:PChar;serr:PChar):Integer;cdecl;external'DLL.DLL'name'CallA';JAVA怎么调用返回多个Pchar的dll我试过返回一个Pchar的没有问题,但是返回多个Pchar的内存释放就有问题.

浅谈char*类型返回值和字符串常量_C 语言

看这样一段简单的程序: #include <stdio.h> char* fun() { return "fun"; } int main() { printf("%s", fun()); return 0; } 这段程序可以正常run,但是最好不要这么做. 因为  直观上你返回了一个局部的东西出去.  你可以再外面定义这个常量,然后返回. 另外,字符串常量不可修改,而char*意味着要修改,故此最好加上const. 以上就是小编为大家带来的浅谈char

c#中如何调用返回值为数组的函数

问题描述 例如publicArrayGet_Weigt(){double[]a=newdouble[3]{1,3,8}returna;}下面要调用上面的这个函数,并且获取a的值,应该咋么调用呢?谢谢大家指教我的分不多了,只能给大家5分了,谢谢 解决方案 解决方案二:publicArrayGet_Weigt(){double[]a=newdouble[3]{1,3,8};returna;}privatevoidbutton2_Click(objectsender,EventArgse){doubl

asp.net mvc 自带的ajax调用返回值的问题

问题描述 view如下:@Ajax.ActionLink("text","action",new{name="ohno"},newAjaxOptions{Confirm="确定删除!",OnBegin="onbegin",OnComplete="oncomplete",OnFailure="onfailure",OnSuccess="onsuccess&qu

PHP调用存储过程返回值不一致问题的解决方法分析_php技巧

本文实例讲述了PHP调用存储过程返回值不一致问题的解决方法.分享给大家供大家参考,具体如下: 今天遇一个同学聊存储过程返回值经常得到意外的值为null, 因为白天有事,晚上给做一个实验放在这里供有相应问题的同学查看一下. 存储过程: delimiter// createprocedureusp_s2(outpar1int) begin selectinet_ntoa(ip),portfromproxy_listlimit5; selectcount(*)intopar1fromproxy_lis

javascript-如何调用JavaScript中confirm()的返回值?

问题描述 如何调用JavaScript中confirm()的返回值? 大家好!我是一名JavaScript初学者,没有其他语言基础,在学习中,我想先对这门语言有一个宏观纵览,有了编程的思路,再回到细节中夯实基本功,以避免"淹死"到那些术语和细节中 我想实现这样一个功能: 1.利用prompt()函数让用户输入姓名 2.利用confirm()函数判断用户的性别 3.confirm()返回真,则alart()显示"你好,××先生! 反之,显示"你好,××女士!"

调用webservice中含返回值为自定义对象的方法时,报ClassCastException错误

问题描述 本人初学webservice,平台用spring+cxf+ibatis,在调用接口中含返回自定义对象的方法时,就会报ClassCastException,即方法:publicList<User>getUserList() 调用返回值为基本类型的方法,则没问题,如:publicIntegergetUserCount(); 困扰很久,包括调用参数中含自定义类型的方法,也会报同样错误,如:publicvoidbImportData(List<User>uList); 请教各位大

WebSphere Message Broker ESQL 调用 jar 的返回值处理

问题描述 使用ESQL调用jar包,获取返回值.我现在有个问题请教下,如果我的返回格式是"<student><name>张三<name><student>",那么我在ESQL中怎么设置来获取name的值?返回的格式有可能很复杂,

群详细页面首次调用group.getMembers()返回值为空

问题描述 群详细信息页面GroupDetailsActivity 在onCreate 调用 List ids = group.getMembers();首次调用返回值都是空的,第二次再调用就有返回值了首次调用时连续调用两次返回也是空的是什么原因呢 解决方案 第二次再调用是什么意思解决方案二:以通讯录导航为例,点群聊,任意选中一个群,此时进入群的通话界面,点击右上角的图标显示群详细资料,这时不显示群成员点击返回,再次点击右上角的图标显示群详细资料,这时就能取到:只要能取到一次,返回到通讯录首页,重