DLL中调用约定和名称修饰(二)

DLL中调用约定和名称修饰(二)

4、thiscall

thiscall调用约定是C++中的非静态类成员函数的默认调用约定。thiscall只能被编译器使用,没有相应的关键字,因此不能被程序员指定。采用thiscall约定时,函数参数按照从右到左的顺序入栈,被调用的函数在返回前清理传送参数的栈,只是另外通过ECX寄存器传送一个额外的参数:this指针。

 

这次的例子中将定义一个类,并在类中定义一个成员函数,代码如下:

 

class CSum

    {

public:

int Add(int a, int b)

{

return (a + b);

}

};

 

void main()

{    

       CSum sum;

       sum.Add(1, 2);

}

 

函数调用部分汇编代码:

 

;CSum sum;

    ;sum.Add(1, 2);

    push                     2                                 ;参数从右到左入栈,先压入2

    push               1                                 ;压入1

    lea          ecx,[ebp-4]                   ;ecx存放了this指针

call         @ILT+5(CSum::Add) (0040100a)        ;调用函数实现

 

函数实现部分汇编代码:

 

;int Add(int a, int b)

       push                     ebp

mov          ebp,esp

sub                esp,44h                        ;多用了一个4bytes的空间用于存放this指针

push               ebx

push               esi

push               edi

push               ecx

lea          edi,[ebp-44h]

mov        ecx,11h

mov          eax,0CCCCCCCCh

rep stos       dword ptr [edi]

pop         ecx

mov          dword ptr [ebp-4],ecx

;return (a + b);

mov          eax,dword ptr [ebp+8]

add         eax,dword ptr [ebp+0Ch]

pop           edi

pop         esi

pop           ebx

mov          esp,ebp

pop           ebp

ret          8                                 ;清栈

5、naked属性

采用上面所述的四种调用约定的函数在进入函数时,编译器会产生代码来保存ESIEDIEBXEBP寄存器中的值,退出函数时则产生代码恢复这些寄存器的内容。对于定义了naked属性的函数,编译器不会自动产生这样的代码,需要你手工使用内嵌汇编来控制函数实现中的堆栈管理。由于naked属性并不是类型修饰符,故必须和__declspec共同使用。下面的这段代码定义了一个使用了naked属性的函数及其实现:

 

__declspec ( naked ) func()

{

int i;

    int j;

      

_asm

{

push              ebp

              mov     ebp, esp

              sub            esp, __LOCAL_SIZE

}

      

    _asm

       {

mov        esp, ebp

              pop         ebp

              ret

       }

}

 

naked属性与本节关系不大,具体请参考MSDN

6、WINAPI

还有一个值得一提的是WINAPI宏,它可以被翻译成适当的调用约定以供函数使用。该宏定义于windef.h之中。下面是在windef.h中的部分内容:

 

#define CDECL             _cdecl

#define WINAPI           CDECL

#define CALLBACK       __stdcall

#define WINAPI        __stdcall

#define APIENTRY     WINAPI

 

       由此可见,WINAPICALLBACKAPIENTRY等宏的作用。

2.名称修饰(Name Decoration

CC++函数在内部(编译和链接)通过修饰名(Decoration Name)识别。函数的修饰名是编译器在编译函数定义或者原型时生成的字符串。编译器在创建.obj文件时对函数名称进行修饰。有些情况下使用函数的修饰名是必要的,如在模块定义文件里头指定输出C++重载函数、构造函数、析构函数,又如在汇编代码里调用CC++函数等。

 

VC++中,函数修饰名由编译类型(CC++)、函数名、类名、调用约定、返回类型、参数等多种因素共同决定。下面分C编译、C++编译(非类成员函数)和C++类及其成员函数编译三种情况说明:

1、C编译时函数名称修饰

当函数使用__cdecl调用约定时,编译器仅在原函数名前加上一个下划线前缀,格式为_functionname。例如:函数int __cdecl Add(int a, int b),输出后为:_Add

 

当函数使用__stdcall调用约定时,编译器在原函数名前加上一个下划线前缀,后面加上一个@符号和函数参数的字节数,格式为_functionname@number。例如:函数int __stdcall Add(int a, int b),输出后为:_Add@8

 

当函数是用__fastcall调用约定时,编译器在原函数名前加上一个@符号,后面是加一个@符号和函数参数的字节数,格式为@functionname@number。例如:函数int __fastcall Add(int a, int b),输出后为:@Add@8

 

    以上改变均不会改变原函数名中的字符大小写。

DLL调用约定名称修饰

03-04

写了一篇关于DLL中调用约定和名称修饰的文章,其中还有很多内容不确定~请大家指教~谢谢~文档中心中的链接:rnhttp://www.csdn.net/Develop/read_article.asp?id=25141rnhttp://www.csdn.net/develop/Read_Article.asp?Id=25142rnhttp://www.csdn.net/develop/Read_Article.asp?Id=25143rn=============================rnDLL中调用约定和名称修饰rnrn调用约定(Calling Convention)是指在程序设计语言中为了实现函数调用而建立的一种协议。这种协议规定了该语言的函数中的参数传送方式、参数是否可变和由谁来处理堆栈等问题。不同的语言定义了不同的调用约定。rnrn在C++中,为了允许操作符重载和函数重载,C++编译器往往按照某种规则改写每一个入口点的符号名,以便允许同一个名字(具有不同的参数类型或者是不同的作用域)有多个用法,而不会打破现有的基于C的链接器。这项技术通常被称为名称改编(Name Mangling)或者名称修饰(Name Decoration)。许多C++编译器厂商选择了自己的名称修饰方案。rnrn因此,为了使其它语言编写的模块(如Visual Basic应用程序、Pascal或Fortran的应用程序等)可以调用C/C++编写的DLL的函数,必须使用正确的调用约定来导出函数,并且不要让编译器对要导出的函数进行任何名称修饰。rn1.调用约定(Calling Convention)rn调用约定用来处理决定函数参数传送时入栈和出栈的顺序(由调用者还是被调用者把参数弹出栈),以及编译器用来识别函数名称的名称修饰约定等问题。在Microsoft VC++ 6.0中定义了下面几种调用约定,我们将结合汇编语言来一一分析它们:rn1、__cdeclrn__cdecl是C/C++和MFC程序默认使用的调用约定,也可以在函数声明时加上__cdecl关键字来手工指定。采用__cdecl约定时,函数参数按照从右到左的顺序入栈,并且由调用函数者把参数弹出栈以清理堆栈。因此,实现可变参数的函数只能使用该调用约定。由于每一个使用__cdecl约定的函数都要包含清理堆栈的代码,所以产生的可执行文件大小会比较大。__cdecl可以写成_cdecl。rnrn下面将通过一个具体实例来分析__cdecl约定:rnrn在VC++中新建一个Win32 Console工程,命名为cdecl。其代码如下:rnrnint __cdecl Add(int a, int b); //函数声明rnrnvoid main()rnrn Add(1,2); //函数调用rnrnrnint __cdecl Add(int a, int b) //函数实现rnrn return (a + b);rnrnrn函数调用处反汇编代码如下:rnrn;Add(1,2);rnpush 2 ;参数从右到左入栈,先压入2rnpush 1 ;压入1rncall @ILT+0(Add) (00401005) ;调用函数实现rnadd esp,8 ;由函数调用清栈rn2、__stdcallrn__stdcall调用约定用于调用Win32 API函数。采用__stdcal约定时,函数参数按照从右到左的顺序入栈,被调用的函数在返回前清理传送参数的栈,函数参数个数固定。由于函数体本身知道传进来的参数个数,因此被调用的函数可以在返回前用一条ret n指令直接清理传递参数的堆栈。__stdcall可以写成_stdcall。rnrn还是那个例子,将__cdecl约定换成__stdcall:rnrnint __stdcall Add(int a, int b)rnrnreturn (a + b);rnrnrn函数调用处反汇编代码:rn rn ; Add(1,2);rnpush 2 ;参数从右到左入栈,先压入2rnpush 1 ;压入1rncall @ILT+10(Add) (0040100f) ;调用函数实现rnrn函数实现部分的反汇编代码:rnrn;int __stdcall Add(int a, int b)rnpush ebprnmov ebp,esprnsub esp,40hrnpush ebxrnpush esirnpush edirnlea edi,[ebp-40h]rnmov ecx,10hrnmov eax,0CCCCCCCChrnrep stos dword ptr [edi]rn;return (a + b);rnmov eax,dword ptr [ebp+8]rnadd eax,dword ptr [ebp+0Ch]rnpop edirnpop esirnpop ebxrnmov esp,ebprnpop ebprnret 8 ;清栈rn3、__fastcallrn__fastcall约定用于对性能要求非常高的场合。__fastcall约定将函数的从左边开始的两个大小不大于4个字节(DWORD)的参数分别放在ECX和EDX寄存器,其余的参数仍旧自右向左压栈传送,被调用的函数在返回前清理传送参数的堆栈。__fastcall可以写成_fastcall。rnrn依旧是相类似的例子,此时函数调用约定为__fastcall,函数参数个数增加2个:rnrnint __fastcall Add(int a, double b, int c, int d)rnrnreturn (a + b + c + d);rnrnrn函数调用部分的汇编代码:rnrn;Add(1, 2, 3, 4);rnpush 4 ;后两个参数从右到左入栈,先压入4rnmov edx,3 ;将int类型的3放入edxrnpush 40000000h ;压入double类型的2rnpush 0rnmov ecx,1 ;将int类型的1放入ecxrncall @ILT+0(Add) (00401005) ;调用函数实现rnrn函数实现部分的反汇编代码:rn rn; int __fastcall Add(int a, double b, int c, int d)rnpush ebprnmov ebp,esprnsub esp,48hrnpush ebxrnpush esirnpush edirnpush ecxrnlea edi,[ebp-48h]rnmov ecx,12hrnmov eax,0CCCCCCCChrnrep stos dword ptr [edi]rnpop ecxrnmov dword ptr [ebp-8],edxrnmov dword ptr [ebp-4],ecxrn;return (a + b + c + d);rnfild dword ptr [ebp-4]rnfadd qword ptr [ebp+8]rnfiadd dword ptr [ebp-8]rnfiadd dword ptr [ebp+10h]rncall __ftol (004011b8)rnpop edirnpop esirnpop ebxrnmov esp,ebprnpop ebprnret 0Ch ;清栈rnrn关键字__cdecl、__stdcall和__fastcall可以直接加在要输出的函数前,也可以在编译环境的Setting...->C/C++->Code Generation项选择。它们对应的命令行参数分别为/Gd、/Gz和/Gr。缺省状态为/Gd,即__cdecl。当加在输出函数前的关键字与编译环境中的选择不同时,直接加在输出函数前的关键字有效。rn4、thiscallrnthiscall调用约定是C++中的非静态类成员函数的默认调用约定。thiscall只能被编译器使用,没有相应的关键字,因此不能被程序员指定。采用thiscall约定时,函数参数按照从右到左的顺序入栈,被调用的函数在返回前清理传送参数的栈,只是另外通过ECX寄存器传送一个额外的参数:this指针。rnrn这次的例子中将定义一个类,并在类中定义一个成员函数,代码如下:rnrnclass CSumrn rnpublic:rnint Add(int a, int b)rnrnreturn (a + b);rnrn;rnrnvoid main()rn rn CSum sum;rn sum.Add(1, 2);rnrnrn函数调用部分汇编代码:rnrn;CSum sum;rn ;sum.Add(1, 2);rn push 2 ;参数从右到左入栈,先压入2rn push 1 ;压入1rn lea ecx,[ebp-4] ;ecx存放了this指针rncall @ILT+5(CSum::Add) (0040100a) ;调用函数实现rnrn函数实现部分汇编代码:rnrn;int Add(int a, int b)rn push ebprnmov ebp,esprnsub esp,44h ;多用了一个4bytes的空间用于存放this指针rnpush ebxrnpush esirnpush edirnpush ecxrnlea edi,[ebp-44h]rnmov ecx,11hrnmov eax,0CCCCCCCChrnrep stos dword ptr [edi]rnpop ecxrnmov dword ptr [ebp-4],ecxrn;return (a + b);rnmov eax,dword ptr [ebp+8]rnadd eax,dword ptr [ebp+0Ch]rnpop edirnpop esirnpop ebxrnmov esp,ebprnpop ebprnret 8 ;清栈rn5、naked属性rn采用上面所述的四种调用约定的函数在进入函数时,编译器会产生代码来保存ESI、EDI、EBX、EBP寄存器中的值,退出函数时则产生代码恢复这些寄存器的内容。对于定义了naked属性的函数,编译器不会自动产生这样的代码,需要你手工使用内嵌汇编来控制函数实现中的堆栈管理。由于naked属性并不是类型修饰符,故必须和__declspec共同使用。下面的这段代码定义了一个使用了naked属性的函数及其实现:rnrn__declspec ( naked ) func()rnrnint i;rn int j;rn rn_asmrnrnpush ebprn mov ebp, esprn sub esp, __LOCAL_SIZErnrn rn _asmrn rnmov esp, ebprn pop ebprn retrn rnrnrnnaked属性与本节关系不大,具体请参考MSDN。rn6、WINAPIrn还有一个值得一提的是WINAPI宏,它可以被翻译成适当的调用约定以供函数使用。该宏定义于windef.h之中。下面是在windef.h中的部分内容:rnrn#define CDECL _cdeclrn#define WINAPI CDECLrn#define CALLBACK __stdcallrn#define WINAPI __stdcallrn#define APIENTRY WINAPIrnrn 由此可见,WINAPI、CALLBACK、APIENTRY等宏的作用。 论坛

VC++、DLL、虚函数、调用约定

08-23

n关于“VC++、DLL、虚函数、调用约定”的一个问题折腾我很久了,希望CSDN的朋友可以助我解决问题。nnDLL里,接口类的虚函数(非纯虚函数),应该怎样调用约定?nn---------------------------------------------------nn背景描述:n一个DLL工程A(接口),有个接口类AI,里面全是纯虚函数。n一个EXE工程B(平台),有个成员变量mc类型是类AI。n一个DLL工程C(游戏),有个类是类AI的子类,即实现类,对类AI的所有接口(纯虚函数)进行了实现。nn原理是:n平台只有一个在跑,而游戏是N个,工程B(平台)的mc被赋值成工程C(游戏)的对象,通过工程A的接口,mc可以调用工程C(游戏)里的函数(接口的实现)。nn问题:n我在开发一个新游戏时,发现工程A(接口)类AI的接口不够用,想新增一个接口,于是加入了一个”虚函数“,注意不是“纯虚函数”,为的是不影响之前所有已有的游戏(不然之前的游戏不作任何改动而编译 会报error C2259: 不能实例化抽象类),即之前的游戏不用实现这个接口,修改工程B(平台)调用这个函数时是工程A(接口)新增的接口,若游戏实现这个接口,就调用游戏里的实现函数;若游戏没有定义这个接口(之前的游戏),则调用工程A(接口)类AI里的虚函数(里面只有一句调试打印)。nn但发现,有的游戏是正常的,有的游戏不正常。不正常的游戏,调试工程B(平台)在调用新接口时提示:nRun-Time Check Failure #0 - The value of ESP was not properly saved across a function call. This is usually a result of calling a function declared with one calling convention with a function pointer declared with a different calling convention.nn百度了一下,很多人说是调名约定的问题。n工程A、工程B、所有的游戏工程C,工程选项里都是 __cdecl (/Gd)。nn于是我在工程A、工程C里下面几种尝试:nvirtual void OnEventABC(int a, bool b); //没写调用约定,有的游戏正常,有的游戏出错nvirtual void __stdcall OnEventABC(int a, bool b); //所有的游戏都出错nvirtual void __cdecl OnEventABC(int a, bool b); //所有的游戏都出错nvirtual void WINAPI OnEventABC(int a, bool b); //所有的游戏都出错nn---------------------------------------------------nn请问大家,怎么解决这个问题,是调名约定的问题,还是其它什么问题?n 问答

VB的DLL调用怎么“DLL调用约定错误”

10-06

"PrinterUsb.dll"里的数据类型及函数如下:rnconst int DEVNUM = 10;rnconst int PATHLEN = 200;rnrntypedef structrnrn char strDevPath[PATHLEN];rnDEVPATH;rnrntypedef structrnrn DEVPATH DevPath[DEVNUM];rn int DevNum;rnDEVINFO;rnrnint GetDevicePath(DEVINFO&);rnbool Open(int PortNum);rnbool Write(char *pBuf,DWORD nNumberOfBytesToWrite,DWORD &NumberOfBytesWritten);rnvoid Close();rnrnrn我在USB里调用DLL,作如下声明:rnrnrnPublic Const DevNum = 10rnPublic Const PATHLEN = 200rnPublic Type DEVPATHrn strDevPath(0 To PATHLEN) As StringrnEnd TypernrnPublic Type DEVINFOrn iDevPath(0 To DevNum) As DEVPATHrn DevNum As IntegerrnEnd TypernrnPublic Declare Function GetDevicePath _rn Lib "PrinterUsb.dll" _rn (ByRef sDevInfo As DEVINFO) _rnAs LongrnrnPublic Declare Function OpenUSB _rn Lib "PrinterUsb.dll" Alias "Open" _rn (ByVal PortNum As Integer) _rnAs BooleanrnrnPublic Declare Function WriteUSB _rn Lib "PrinterUsb.dll" Alias "Write" _rn (ByVal pBuf As String, _rn ByVal nNumberOfBytesToWrite As Long, _rn ByVal nNumberOfBytesWritten As Long) _rnAs BooleanrnrnPublic Declare Sub CloseUSB _rn Lib "PrinterUsb.dll" Alias "Close" ()rnrnrn程序如下:rnPrivate Sub cmdUSBTest_Click()rn Dim MyDevInfo As DEVINFOrn Dim ESC As String: ESC = Chr(27)rn Dim strCmd As Stringrn Dim nNumberOfBytesToWrite As Long: nNumberOfBytesToWrite = 0rn Dim nNumberOfBytesWritten As Long: nNumberOfBytesWritten = 10rn rn strCmd = "hello"rn rn rn GetDevicePath MyDevInforn If MyDevInfo.DevNum = 0 Thenrn MsgBox "未检测到USB设备!"rn Endrn End Ifrn rn If OpenUSB(0) = False Thenrn MsgBox "打开USB设备失败!"rn Endrn End Ifrn rn WriteUSB strCmd, nNumberOfBytesToWrite, nNumberOfBytesWrittenrn rn CloseUSBrn rn rnEnd Subrnrnrnrn执行GetDevicePath MyDevInfo时就出现“实时错误49,DLL调用约定错误”rn我把rnPublic Declare Function GetDevicePath _rn Lib "PrinterUsb.dll" _rn (ByRef sDevInfo As DEVINFO) _rnAs Longrn改成rnPublic Declare Function GetDevicePath _rn Lib "PrinterUsb.dll" _rn (ByVal sDevInfo As DEVINFO) _rnAs Longrn就出现“编译错误:用户类型不能用”。rnrn现在怎么办,哪儿错了,要怎么改,原因是什么呢,谢谢!rn 论坛

请教高手:VB dll 调用约定错误!!

02-29

各位高手,我的VB调用DLL,在运行时出现了 dll 调用约定错误! 程序如下,请各位大虾帮忙解决一下!!感恩。。rnrnVB程序:rnrnrnrnOption Explicitrnrn'USB User InterfacernPublic Declare Function Read_USB Lib "DS5000USB_UI.dll" (ByVal mType As Long, ByVal wLength As Long, pBuffer As Any) As BooleanrnPublic Declare Function Write_USB Lib "DS5000USB_UI.dll" (ByVal cChar As Long) As BooleanrnrnGlobal Const USB_READ_CMD_REDAY = 0rnGlobal Const USB_READ_CMD_DATA = 1rnGlobal Const ARRAYSIZE = 1024 ' Size of read bufferrnGlobal DSO_IOInitOK As BooleanrnGlobal USB_TimeOutTimer As Long 'USB´«Êä½áÊøʱ¼ärnrnrnSub USB_Init()rn' ========================================================================rn'rn' INITIALIZATION SECTIONrn'rn' ========================================================================rnrn ' The application brings the oscilloscope online using ildev. Arn ' device handle, Dev, is returned and is used in all subsequentrn ' calls to the device.rn Dim retcode As Booleanrn Dim ValueStr As String * ARRAYSIZErn Dim buf(255) As Bytern ' The application reads the ASCII string from the oscilloscopern ' into the ValueStr variable.rn retcode = Read_USB(USB_READ_CMD_REDAY, 1, buf(0))rn rn If retcode = False Thenrn MsgBox "Cann't Connect to USB Device", 48, "USB Init"rn DSO_IOInitOK = Falsern Elsern DSO_IOInitOK = Truern End Ifrn rnEnd SubrnSub SendToUSB(cmd As String)rn Dim retcode As Booleanrn Dim buf As Stringrn Dim temp As Longrn Dim i As Integerrn rn buf = cmd + Chr$(13)rnrn ' The application writes the text in ScopeCommand to thern ' oscilloscope.rn For i = 1 To Len(cmd) + 1rn temp = Asc(buf)rn buf = Right(buf, Len(cmd) + 1 - i)rn retcode = Write_USB(temp)rn If retcode = False Thenrn MsgBox "Cann't Connect to USB Device", 48, "USB Send Message"rn Exit Forrn End Ifrn Next irnrnEnd SubrnPublic Function ReadUSB() As Stringrnrn Dim retcode As Booleanrn Dim tmpStr As Stringrn Dim buffer(256) As Bytern Dim i, size As Longrn ' The application reads the ASCII string from the oscilloscopern ' into the ValueStr variable.rn USB_TimeOutTimer = 0rn buffer(0) = 0rn While (buffer(0) = 0 And USB_TimeOutTimer < 20)rn retcode = Read_USB(USB_READ_CMD_REDAY, 1, buffer(0))rn If retcode = False Thenrn MsgBox "Can't Connect to USB Device", 48, "USB Read Message"rn ReadUSB = ""rn Exit Functionrn End Ifrn DoEventsrn Wendrn If USB_TimeOutTimer > 19 Thenrn MsgBox "Read USB time out", 48, "USB Read Message"rn tmpStr = ""rn Elsern size = buffer(0)rn retcode = Read_USB(USB_READ_CMD_DATA, size, buffer(0))rn If retcode = False Thenrn MsgBox "Cann't Connect to USB Device", 48, "USB Read Message"rn ReadUSB = ""rn Exit Functionrn End Ifrn tmpStr = ""rn For i = 0 To size - 1rn If (buffer(i) = 10) Thenrn Exit Forrn End Ifrn tmpStr = tmpStr + Chr(buffer(i))rn Next irn End Ifrn ReadUSB = tmpStrrn rnEnd FunctionrnrnrnrnrnDLL函数定义:rnrn(DLL头文件)rnrn// DS5000USB_UI.h : main header file for the DS5000USB_UI DLLrn//rnrn#if !defined(AFX_DS5000USB_UI_H__A004624B_F508_4C1D_B0A9_5ABF16885DC8__INCLUDED_)rn#define AFX_DS5000USB_UI_H__A004624B_F508_4C1D_B0A9_5ABF16885DC8__INCLUDED_rnrn#if _MSC_VER > 1000rn#pragma oncern#endif // _MSC_VER > 1000rnrn#ifndef __AFXWIN_H__rn #error include 'stdafx.h' before including this file for PCHrn#endifrnrn#include "resource.h" // main symbolsrnrn#define USB_CTRL_TYPE_LEN 0//¶Á´«ÊäµÄÊý¾ÝµÄ³¤¶Èrn#define USB_CTRL_TYPE_DATA 1//¶Á´«ÊäµÄÊý¾Ýrnrnextern "C" BOOL EXPORT __stdcall Control_Command_Send(INT devIndex,INT mRequest,INT wValue,INT wIndex,INT wLength);rnextern "C" BOOL EXPORT __stdcall Control_Command_Receive(INT devIndex,INT mRequest,INT wValue,INT wIndex,INT wLength,PUCHAR mBuffer);rnextern "C" BOOL EXPORT __stdcall Bulk_DataTransfer_Read(INT devIndex,INT wLength,PUCHAR mBuffer);rnextern "C" BOOL EXPORT __stdcall Bulk_DataTransfer_Write(INT devIndex,INT wLength,PUCHAR mBuffer);rnextern "C" INT EXPORT __stdcall GetDeviceNum();//»ñÈ¡µ±Ç°ÏµÍ³ÖеÄRIGOL ·ÇTMCÉ豸×ÜÊýrn/*******************************************************************************rnrn ** º¯ÊýÃû³Æ: Read_USB rn ** ÊäÈë²ÎÊýrn ** devIndex --- É豸±àºÅ rn ** type --- ¶ÁÈ¡ÀàÐÍΪÊý¾Ý³¤¶È(USB_CTRL_TYPE_LEN)»òÊý¾ÝÄÚÈÝ(USB_CTRL_TYPE_DATA)rn ** wLength --- ±¾´Î¶ÁÈ¡µÄ³¤¶Èrn ** mBuffer --- ´æ´¢¶ÁÈ¡Êý¾ÝµÄ¿Õ¼äÖ¸Õërn **rn ** Êä³ö²ÎÊý:rn ** ·µ»ØÀàÐÍ --- BOOLÀàÐÍrn **rn ** Ãè Êö: ¶ÁÈ¡USBÊý¾Ýrn********************************************************************************/rnextern "C" BOOL EXPORT __stdcall Read_USB(INT devIndex,INT type,INT wLength,PUCHAR mBuffer);rn/*******************************************************************************rnrn ** º¯ÊýÃû³Æ: Write_USB rn ** ÊäÈë²ÎÊýrn ** devIndex --- É豸±àºÅ rn ** chr --- Ҫͨ¹ýUSB·¢Ë͵ÄÊý¾Ýrn **rn ** Êä³ö²ÎÊý:rn ** ·µ»ØÀàÐÍ --- BOOLÀàÐÍrn **rn ** Ãè Êö: ·¢ËÍUSBÊý¾Ýrn********************************************************************************/rnextern "C" BOOL EXPORT __stdcall Write_USB(INT devIndex,UCHAR chr);rnrnHANDLE OpenDeviceByIndex(INT index);rnBOOL CloseDeviceByIndex(INT index);rn//BOOL Close_Device_Handle();rnrnrn#define MAX_BULK_INBUF_SIZE 4096rn#define MAX_BULK_OUTBUF_SIZE 4096rnrn#define MAX_CONTROL_INBUF_SIZE 512rn#define MAX_CONTROL_OUTBUF_SIZE 512rnrnrnBOOL CloseIfOpen(VOID);rnBOOL Exit(INT res);rnrnextern HANDLE OpenByInterface(rn GUID* pClassGuid, // points to the GUID that identifies the interface classrn DWORD instance, // specifies which instance of the enumerated devices to openrn PDWORD pError // address of variable to receive error statusrn );rnrn/////////////////////////////////////////////////////////////////////////////rn// CDS5000USB_UIApprn// See DS5000USB_UI.cpp for the implementation of this classrn//rnrnrnclass CDS5000USB_UIApp : public CWinApprnrnpublic:rn CDS5000USB_UIApp();rnrn// Overridesrn // ClassWizard generated virtual function overridesrn //AFX_VIRTUAL(CDS5000USB_UIApp)rn public:rn virtual void OnFinalRelease();rn //AFX_VIRTUALrnrn //AFX_MSG(CDS5000USB_UIApp)rn // NOTE - the ClassWizard will add and remove member functions here.rn // DO NOT EDIT what you see in these blocks of generated code !rn //AFX_MSGrn DECLARE_MESSAGE_MAP()rn;rnrnrn/////////////////////////////////////////////////////////////////////////////rnrn//AFX_INSERT_LOCATIONrn// Microsoft Visual C++ will insert additional declarations immediately before the previous line.rnrn#endif // !defined(AFX_DS5000USB_UI_H__A004624B_F508_4C1D_B0A9_5ABF16885DC8__INCLUDED_)rnrn 论坛

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