学习笔录(持续更新)

=============小功能模块函数收集================================
static short OutputToFile(LPCTSTR strFile, LPCTSTR szText)
{
FILE *file;
if (fopen_s( &file, strFile, "a+" ) == 0 )
{
fseek(file,0,SEEK_END);
fwrite(szText,strlen(szText),1,file);//把字符串内容写入到文件
fclose(file);
}
return 1;
}






void log(const TCHAR * pszFormat, ...)
{
#ifndef _DEBUG
return;
#endif
LPTSTR pEnd = NULL;
size_t nRemain = 0;
TCHAR szText[1024] = {0};


SYSTEMTIME localTime = {0};
GetLocalTime(&localTime);


StringCchPrintfEx(szText, _countof(szText), &pEnd, &nRemain, 0,
_T("[%04d-%02d-%02d][%02d:%02d:%02d:%03d][%d][%d]"), localTime.wYear,
localTime.wMonth, localTime.wDay, localTime.wHour,
localTime.wMinute, localTime.wSecond, localTime.wMilliseconds,
GetCurrentProcessId(), GetCurrentThreadId());


va_list vlArgs;
va_start(vlArgs, pszFormat);
StringCchVPrintfEx(pEnd, nRemain, &pEnd, &nRemain, 0, pszFormat, vlArgs);
va_end(vlArgs);
if ( nRemain >= 2 )
{
StringCchCopy(pEnd, nRemain, _T("\n"));
}
OutputDebugString(szText);


#ifdef FC_LOG_TO_File
TCHAR szFile[MAX_PATH]={0};
GetModuleFileName(NULL,szFile,MAX_PATH);
StringCchCat(szFile,MAX_PATH,".log");
OutputToFile("C:\\t.log",szText);
#endif
}






功能:演示等待通过CreateProcess创建的进程结束
#include <stdio.h>
#include <Windows.h>


int main()
{
STARTUPINFO si;
PROCESS_INFORMATION pi;


memset( &si, 0x00, sizeof(si) );
si.cb = sizeof(si);
memset( &pi, 0x00, sizeof(pi) );


// Start the child process. 
if ( CreateProcess( L"c:\\windows\\system32\\cmd.exe",   // No module name (use command line)
NULL,        // Command line
NULL,           // Process handle not inheritable
NULL,           // Thread handle not inheritable
FALSE,          // Set handle inheritance to FALSE
0,              // No creation flags
NULL,           // Use parent's environment block
NULL,           // Use parent's starting directory 
&si,            // Pointer to STARTUPINFO structure
&pi )
)
{
DWORD oldTime =GetTickCount();
DWORD dwRetun=0;
WaitForSingleObject(pi.hProcess,INFINITE);
DWORD newTime=GetTickCount();
DWORD dwTime=(newTime-oldTime)/1000;
GetExitCodeProcess(pi.hProcess,&dwRetun);

printf("程序运时长: dwTime = %d 退出时返回值: %d\n", dwTime, dwRetun);
getchar();
}


return 0;
}




获取系统版本信息:GetVersionEx
获取文件属性信息:GetFileAttributes
SafeArrayGetLBound
SafeArrayGetElement


ConvertBSTRToString
ConvertStringToBSTR


=======关于HTTP下载操作的函数=================
InternetOpen
InternetSetOption可以实现代理调置
InternetConnect
InternetReadFile
HttpOpenRequest
HttpAddRequestHeaders
HttpSendRequest
HttpQueryInfo




=======关于管道操作的函数=================
CreateNamedPipe
ConnectNamedPipe
DisconnectNamedPipe




=======关于注册表操作的函数=================
RegOpenKeyEx
RegQueryInfoKey
RegEnumKeyEx
RegQueryValueEx
RegCreateKey
RegSetValueEx
RegCloseKey




=======关于INI文件操作的函数=================
GetPrivateProfileString
WritePrivateProfileString


=======关于令牌的函数=================
OpenProcessToken
GetTokenInformation
DuplicateTokenEx
LookupPrivilegeValue
AdjustTokenPrivileges
SetThreadToken




=======关于资源系列函数=================
FindResource
LoadResource
SizeofResource
LockResource 




=======关于环境变量系列函数=================
ExpandEnvironmentStrings
GetEnvironmentStrings 
SetEnvironmentVariable




=========关于字符转换函数===============
MultiByteToWideChar
WideCharToMultiByte


===========中关于启动方式、程序快捷方式创建、===========
关于自启动方式:
注册表中Run自启动
启动菜单栏里创建启动快捷方式
计划任务启动





-------------根据shobjidl.h头文件整理ShellObjects------------
ShellDesktop -- CLSID_ShellDesktop
ShellFSFolder -- CLSID_ShellFSFolder
NetworkPlaces -- CLSID_NetworkPlaces
ShellLink -- CLSID_ShellLink
QueryCancelAutoPlay -- CLSID_QueryCancelAutoPlay
DriveSizeCategorizer -- CLSID_DriveSizeCategorizer
DriveTypeCategorizer -- CLSID_DriveTypeCategorizer
FreeSpaceCategorizer -- CLSID_FreeSpaceCategorizer
TimeCategorizer -- CLSID_TimeCategorizer
SizeCategorizer -- CLSID_SizeCategorizer
AlphabeticalCategorizer -- CLSID_AlphabeticalCategorizer
MergedCategorizer -- CLSID_MergedCategorizer
ImageProperties -- CLSID_ImageProperties
PropertiesUI -- CLSID_PropertiesUI
UserNotification -- CLSID_UserNotification
CDBurn -- CLSID_CDBurn
TaskbarList -- CLSID_TaskbarList
StartMenuPin -- CLSID_StartMenuPin
WebWizardHost -- CLSID_WebWizardHost
PublishDropTarget -- CLSID_PublishDropTarget
PublishingWizard -- CLSID_PublishingWizard
InternetPrintOrdering -- CLSID_InternetPrintOrdering
FolderViewHost -- CLSID_FolderViewHost
ExplorerBrowser -- CLSID_ExplorerBrowser
ImageRecompress -- CLSID_ImageRecompress
TrayBandSiteService -- CLSID_TrayBandSiteService
TrayDeskBand -- CLSID_TrayDeskBand
AttachmentServices -- CLSID_AttachmentServices
DocPropShellExtension -- CLSID_DocPropShellExtension
ShellItem -- CLSID_ShellItem
NamespaceWalker -- CLSID_NamespaceWalker
FileOperation -- CLSID_FileOperation
FileOpenDialog -- CLSID_FileOpenDialog
FileSaveDialog -- CLSID_FileSaveDialog
KnownFolderManager -- CLSID_KnownFolderManager
FSCopyHandler -- CLSID_FSCopyHandler
SharingConfigurationManager -- CLSID_SharingConfigurationManager
PreviousVersions -- CLSID_PreviousVersions
NetworkConnections -- CLSID_NetworkConnections
NamespaceTreeControl -- CLSID_NamespaceTreeControl
IENamespaceTreeControl -- CLSID_IENamespaceTreeControl
ScheduledTasks -- CLSID_ScheduledTasks
ApplicationAssociationRegistration -- CLSID_ApplicationAssociationRegistration
ApplicationAssociationRegistrationUI -- CLSID_ApplicationAssociationRegistrationUI
SearchFolderItemFactory -- CLSID_SearchFolderItemFactory
OpenControlPanel -- CLSID_OpenControlPanel
ComputerInfoAdvise -- CLSID_ComputerInfoAdvise
NetworkExplorerFolder -- CLSID_NetworkExplorerFolder








=========================关于证书信息==================================
MSDN中有专门一节关于"Cryptography Functions"
CertFindCertificateInStore
CertGetNameString 
CryptMsgGetParam 


=========================获取文件版本信息==================================
MSDN中有专门一节关于"Version Information"
GetFileVersionInfoSize
GetFileVersionInfo
VerQueryValue


================================================================================================


CreateWaitableTimer
SetWaitableTimer
CancelWaitableTimer




SetFilePointer
FlushFileBuffers
SetEndOfFile




EnumPropsEx
EnumWindows


GetClassName 


GetWindowThreadProcessId


SHGetDesktopFolder
SHGetSpecialFolderPath
SHGetSpecialFolderLocation
SHGetPathFromIDList




GlobalGetAtomName 


SHUnicodeToAnsi
SHUnicodeToUnicode


VirtualProtect
VirtualQuery


关于Module系列函数
GetModuleHandle
GetModuleFileName
GetModuleBaseName 
GetModuleInformation




transform这样的一个函数,将某个操作应用于指定范围
string sModName = lpModName;
transform(sModName.begin(), sModName.end(), sModName.begin(), tolower);


GetMappedFileName


GetProcessImageFileName
GetLogicalDriveStrings
QueryDosDevice


关于路径的一系列处理函数
PathFindFileName
PathRemoveFileSpec
PathAppend
PathFileExists
PathIsDirectory
PathSkipRoot






CommandLineToArgvW
CDefFolderMenu_Create2
StringCchPrintfEx 
StringCchPrintf
StringCchVPrintf


StrStrNIW
StrCmpIC
StrCmpIW


GetWindowLong 
SetWindowLong


CallWindowProc
DefWindowPro


FindWindowEx


//获取字体高度
HDC hTabWndDc = GetWindowDC(hPageWnd);
TEXTMETRIC tmPageTxt;
GetTextMetrics(hTabWndDc, &tmPageTxt);
ReleaseDC(hPageWnd, hTabWndDc);




ConvertStringSecurityDescriptorToSecurityDescriptor
GetSecurityDescriptorSacl
SetSecurityInfo


-----------------关于内联汇编中使用机器码编码------------------------
下面的示例实现了一个由用户态进入内核态的方法,下面的硬编码在WIN7系统VS2010中无法运行
__declspec(naked) void __stdcall InKernel()
{
__asm
{
mov edx,esp
//sysenter
_emit 0xF0
_emit 0x34
}
}




-----------------VS2010中使用Alt+G快速定位函数或变量定义位置------------------------
VS2010中使用Alt+G快速定位函数或变量定义位置




-----------------关于OD的几个快捷键--------------------------------
F4运行到所选
F7单步跟入
F8单步步过 
“-”表示返回到先前位置




----------------------------------------------------------------------
关于地址有效性判定
IsBadCodePtr
IsBadReadPtr
IsBadStringPtr
IsBadWritePtr 
----------------------------------------------------------------------


GetModuleHandle
GetModuleFileName
GetModuleBaseName 
GetModuleInformation


----------------------------------------------------------------------
StackWalk编程实现栈的回溯这里用的WINAPI,这里一个关键的参数EIP\ESP\EBP
EAX = CCCCCCCC EBX = 7FFD3000 ECX = 00000000 EDX = 77676194 ESI = 0021F818 EDI = 0021F4C0 
EIP = 00DD195E ESP = 0021F3F4 EBP = 0021F4C0 EFL = 00000206 


----------------------------------------------------------------------
VirtualProtect修改内存的读、写、执行属性




---------------------关于ToolHelp函数------------------------------
关于ToolHelp函数的一些有用的函数:
Tool Help Functions
The following functions are part of the tool help library.


Function Description 
CreateToolhelp32Snapshot Takes a snapshot of the specified processes, as well as the heaps, modules, and threads used by these processes. 
Heap32First Retrieves information about the first block of a heap that has been allocated by a process. 
Heap32ListFirst Retrieves information about the first heap that has been allocated by a specified process. 
Heap32ListNext Retrieves information about the next heap that has been allocated by a process. 
Heap32Next Retrieves information about the next block of a heap that has been allocated by a process. 
Module32First Retrieves information about the first module associated with a process. 
Module32Next Retrieves information about the next module associated with a process or thread. 
Process32First Retrieves information about the first process encountered in a system snapshot. 
Process32Next Retrieves information about the next process recorded in a system snapshot. 
Thread32First Retrieves information about the first thread of any process encountered in a system snapshot. 
Thread32Next Retrieves information about the next thread of any process encountered in the system memory snapshot. 
Toolhelp32ReadProcessMemory Copies memory allocated to another process into an application-supplied buffer. 


----------------------------------------------------------------------
在学习SHGetFolderPath的进候居然看到一个路径链接的函数PathAppend,该目录下有一系列关于路径操作及URL操作的集成函数(很不错)
WinExec函数,通过命令行执行EXE
ShellExecute函数


----------------------------------------------------------------------
关于一些WINDOWS中字符数据类型的定义
//
// Neutral ANSI/UNICODE types and macros
//
#ifdef  UNICODE                     // r_winnt


#ifndef _TCHAR_DEFINED
typedef WCHAR TCHAR, *PTCHAR;
typedef WCHAR TBYTE , *PTBYTE ;
#define _TCHAR_DEFINED
#endif /* !_TCHAR_DEFINED */


typedef LPWCH LPTCH, PTCH;
typedef LPCWCH LPCTCH, PCTCH;
typedef LPWSTR PTSTR, LPTSTR;
typedef LPCWSTR PCTSTR, LPCTSTR;
typedef LPUWSTR PUTSTR, LPUTSTR;
typedef LPCUWSTR PCUTSTR, LPCUTSTR;
typedef LPWSTR LP;
typedef PZZWSTR PZZTSTR;
typedef PCZZWSTR PCZZTSTR;
typedef PUZZWSTR PUZZTSTR;
typedef PCUZZWSTR PCUZZTSTR;
typedef PNZWCH PNZTCH;
typedef PCNZWCH PCNZTCH;
typedef PUNZWCH PUNZTCH;
typedef PCUNZWCH PCUNZTCH;
#define __TEXT(quote) L##quote      // r_winnt


#else   /* UNICODE */               // r_winnt


#ifndef _TCHAR_DEFINED
typedef char TCHAR, *PTCHAR;
typedef unsigned char TBYTE , *PTBYTE ;
#define _TCHAR_DEFINED
#endif /* !_TCHAR_DEFINED */


typedef LPCH LPTCH, PTCH;
typedef LPCCH LPCTCH, PCTCH;
typedef LPSTR PTSTR, LPTSTR, PUTSTR, LPUTSTR;
typedef LPCSTR PCTSTR, LPCTSTR, PCUTSTR, LPCUTSTR;
typedef PZZSTR PZZTSTR, PUZZTSTR;
typedef PCZZSTR PCZZTSTR, PCUZZTSTR;
typedef PNZCH PNZTCH, PUNZTCH;
typedef PCNZCH PCNZTCH, PCUNZTCH;
#define __TEXT(quote) quote         // r_winnt


#endif /* UNICODE */                // r_winnt
#define TEXT(quote) __TEXT(quote)   // r_winnt


----------------------------------------------------------------------


VS2010编译环境中选择编译是按C++方式还是C方式来编译代码的选项位置:
右键工程属性--属性对话框中
Configuration Properties
|
  C/C++
|
Advanced
|
Compile As选项指定默认,C编译方式,C++编译方式
----------------------------------------------------------------------


VS2010编译环境中选择指定编译的程序为控制台程序还是窗口程序:
右键工程属性--属性对话框中
Configuration Properties
|
  Linker
|
  System
|
SubSystem选项指定Console (/SUBSYSTEM:CONSOLE)或Windows (/SUBSYSTEM:WINDOWS)
----------------------------------------------------------------------


VS2010编译环境中选择指定编译的程序不进行缓冲区溢出检测(测试缓冲区溢出时修改此项,不修改些项测试无效果):
右键工程属性--属性对话框中
Configuration Properties
|
  C/C++
|
  Code Generation
|
Buffer Security Check选项指定No(/GS-)
----------------------------------------------------------------------


__try{
//这里发生异常
}__except(EXCEPTION_EXECUTE_HANDLER) //捕获异常并继续执行下面的代码
{
unsigned long Code = GetExceptionCode();
printf("Code = 0x%08X\n", Code);
}
----------------------------------------------------------------------


调用者自己恢复栈平衡,用于可变参函数,调用约定为__cdecl,汇编代码表现
push 参数
call 函数
add esp,4




被调用者自己恢复栈平衡__stdcall
push 参数
call 函数




采用寄存器传参__fastcall
mov edx,参数
mov ecx,参数
call 函数


以上各种调用约定对应的编译器选项 /Gz (stdcall)、/Gr (fastcall)、/Gd (cdecl)


说明:在MSDN帮助文档中可以搜关键字__cdcel
----------------------------------------------------------------------
关于调用不同调用约定的C函数名修饰:
C 函数的修饰形式取决于其声明中使用的调用约定,如下所示。


调用约定              修饰
 
__cdecl(默认值)     前导下划线 (_)
 
__stdcall             前导下划线 (_) 和结尾 at 符 (@),后面跟表示参数列表中的字节数的数字
 
__fastcall            与 __stdcall 相同,但前置符不是下划线,而是 @ 符


实例分析:(自己动手实践验证VS2010)
函数原型:    修饰后的名称:
int __fastcall fun3(int a, int b);   @fun3@8
int __stdcall fun2(int a, int b);   _fun2@8
int __cdecl fun1(int a, int b);   _fun1




------------------------C++ 修饰名的格式----------------------------------------------
C++ 函数的修饰名包含下列信息:


函数名。


函数所属的类(如果函数是成员函数)。这可能包括封装函数的类的类,等等。


函数所属的命名空间(如果函数是某个命名空间的组成部分)。


函数的参数类型。


调用约定。


函数的返回类型。


函数名和类名在修饰名中以代码形式存在。修饰名的其余部分是仅对编译器和链接器具有内部意义的代码。下面是未修饰的和修饰的 C++ 名称的示例。


未修饰名 修饰名
 
int a(char){int i=3;return i;};        ?a@@YAHD@Z 
 
void __stdcall b::c(float){};          ?c@b@@AAGXM@Z 
 


------------Argument Passing and Naming Conventions---------------------------------
Microsoft Specific


All arguments are widened to 32 bits when they are passed. Return values are also widened to 32 bits and returned in the EAX register, except for 8-byte structures, which are returned in the EDX:EAX register pair. Larger structures are returned in the EAX register as pointers to hidden return structures. Parameters are pushed onto the stack from right to left. Structures that are not PODs will not be returned in registers.


The compiler generates prolog and epilog code to save and restore the ESI, EDI, EBX, and EBP registers, if they are used in the function.


Note: 
When a struct, union, or class is returned from a function by value, all definitions of the type need to be the same, else the program may fail at runtime.
 


For information on how to define your own function prolog and epilog code, see (Naked Function Calls).


The following calling conventions are supported by the Visual C/C++ compiler.


Keyword Stack cleanup Parameter passing
 
__cdecl Caller Pushes parameters on the stack, in reverse order (right to left)
 
__clrcall n/a Load parameters onto CLR expression stack in order (left to right).
 
__stdcall Callee Pushes parameters on the stack, in reverse order (right to left)
 
__fastcall Callee Stored in registers, then pushed on stack
 
__thiscall Callee Pushed on stack; this pointer stored in ECX
 




--------------------------Naked Function Calls关键字在MSDN中--------------------------------------------
Microsoft Specific
Functions declared with the naked attribute are emitted without prolog or epilog code, enabling you to write your own custom prolog/epilog sequences using the inline assembler. Naked functions are provided as an advanced feature. They enable you to declare a function that is being called from a context other than C/C++, and thus make different assumptions about where parameters are, or which registers are preserved. Examples include routines such as interrupt handlers. This feature is particularly useful for writers of virtual device drivers (VxDs). 


实例函数原型:
__declspec( naked ) int func( int a, int b )
{
__asm ret
}


--------------------------Considerations for Writing Prolog/Epilog Code--------------------------
Microsoft Specific
Before writing your own prolog and epilog code sequences, it is important to understand how the stack frame is laid out. It is also useful to know how to use the __LOCAL_SIZE symbol.


Stack Frame Layout
push        ebp                ; Save ebp
mov         ebp, esp           ; Set stack frame pointer
sub         esp, localbytes    ; Allocate space for locals
push        <registers>        ; Save registers


The localbytes variable represents the number of bytes needed on the stack for local variables, and the <registers> variable is a placeholder that represents the list of registers to be saved on the stack. After pushing the registers, you can place any other appropriate data on the stack. The following is the corresponding epilog code:




pop         <registers>   ; Restore registers
mov         esp, ebp      ; Restore stack pointer
pop         ebp           ; Restore ebp
ret                       ; Return from function


The stack always grows down (from high to low memory addresses). The base pointer (ebp) points to the pushed value of ebp. The locals area begins at ebp-2. To access local variables, calculate an offset from ebp by subtracting the appropriate value from ebp.


__LOCAL_SIZE
The compiler provides a symbol, __LOCAL_SIZE, for use in the inline assembler block of function prolog code. This symbol is used to allocate space for local variables on the stack frame in custom prolog code.


The compiler determines the value of __LOCAL_SIZE. Its value is the total number of bytes of all user-defined local variables and compiler-generated temporary variables. __LOCAL_SIZE can be used only as an immediate operand; it cannot be used in an expression. You must not change or redefine the value of this symbol. For example:


mov        eax, __LOCAL_SIZE           ;Immediate operand--Okay
mov        eax, [ebp - __LOCAL_SIZE]   ;Error


The following example of a naked function containing custom prolog and epilog sequences uses the __LOCAL_SIZE symbol in the prolog sequence:


// the__local_size_symbol.cpp
// processor: x86
__declspec ( naked ) int main() {
   int i;
   int j;


   __asm {      /* prolog */
      push   ebp
      mov      ebp, esp
      sub      esp, __LOCAL_SIZE
      }
      
   /* Function body */
   __asm {   /* epilog */
      mov      esp, ebp
      pop      ebp
      ret
      }
}








------------------------__declspec keyword关键字在MSDN中----------------------------------------------
The extended attribute syntax for specifying storage-class information uses the __declspec keyword, which specifies that an instance of a given type is to be stored with a Microsoft-specific storage-class attribute listed below. Examples of other storage-class modifiers include the static and extern keywords. However, these keywords are part of the ANSI specification of the C and C++ languages, and as such are not covered by extended attribute syntax. The extended attribute syntax simplifies and standardizes Microsoft-specific extensions to the C and C++ languages.


decl-specifier: 
__declspec ( extended-decl-modifier-seq )


extended-decl-modifier-seq: 
extended-decl-modifieropt


extended-decl-modifier extended-decl-modifier-seq


extended-decl-modifier: 
align(#) 


allocate("segname") 


appdomain 


deprecated 


dllimport 


dllexport 


jitintrinsic


naked 


noalias 


noinline 


noreturn 


nothrow 


novtable 


process 


property({get=get_func_name|,put=put_func_name}) 


restrict 


selectany 


thread 


uuid("ComObjectGUID")


White space separates the declaration modifier sequence. Examples appear in later sections.


Extended attribute grammar supports these Microsoft-specific storage-class attributes: align, allocate, appdomain, deprecated, dllexport, dllimport, jitintrinsic, naked, noalias, noinline, noreturn, nothrow, novtable, process, restrict, selectany, and thread. It also supports these COM-object attributes: property and uuid. 


The dllexport, dllimport, naked, noalias, nothrow, property, restrict, selectany, thread, and uuid storage-class attributes are properties only of the declaration of the object or function to which they are applied. The thread attribute affects data and objects only. The naked attribute affects functions only. The dllimport and dllexport attributes affect functions, data, and objects. The property, selectany, and uuid attributes affect COM objects.


The __declspec keywords should be placed at the beginning of a simple declaration. The compiler ignores, without warning, any __declspec keywords placed after * or & and in front of the variable identifier in a declaration.


A __declspec attribute specified in the beginning of a user-defined type declaration applies to the variable of that type. For example:


  Copy Code 
__declspec(dllimport) class X {} varX;
 


In this case, the attribute applies to varX. A __declspec attribute placed after the class or struct keyword applies to the user-defined type. For example:


  Copy Code 
class __declspec(dllimport) X {};
 


In this case, the attribute applies to X.


The general guideline for using the __declspec attribute for simple declarations is as follows:


  Copy Code 
decl-specifier-seqdeclarator-list;
 


The decl-specifier-seq should contain, among other things, a base type (e.g. int, float, a typedef, or a class name), a storage class (e.g. static, extern), or the __declspec extension. The init-declarator-list should contain, among other things, the pointer part of declarations. For example:


  Copy Code 
__declspec(selectany) int * pi1 = 0;   //OK, selectany & int both part of decl-specifier
int __declspec(selectany) * pi2 = 0;   //OK, selectany & int both part of decl-specifier
int * __declspec(selectany) pi3 = 0;   //ERROR, selectany is not part of a declarator
 


The following code declares an integer thread local variable and initializes it with a value:


  Copy Code 
// Example of the __declspec keyword
__declspec( thread ) int tls_i = 1;
 


----------------------Calling C Functions in Inline Assembly内联汇编中调用C库函数---------Inline Assembler关键字----------------------
#include <stdio.h>
#include <Windows.h>


char format[] = "%s %s\n";
char hello[] = "Hello";
char world[] = "world";


//在内嵌汇编中调用C库函数
int __declspec(naked) main( void )
{
__asm
{
push offset world
push offset hello
push offset format
call dword ptr printf //这里要加上dword ptr
add esp,0ch //这里要自己维护栈的平衡


call dword ptr getchar


xor eax,eax
push eax
push offset world
push offset hello
push eax
call dword ptr MessageBox


ret //自已调用返回指令返回
}
}








----------------------------有两种从 DLL 导出函数的方法------------------------------------------
.DLL 文件的布局与 .exe 文件非常相似,但有一个重要的差异:DLL 文件包含导出表。导出表包含 DLL 导出到其他可执行文件的每个函数的名称。这些函数是 DLL 中的入口点;只有导出表中的函数可由其他可执行文件访问。DLL 中的任何其他函数都是 DLL 私有的。通过使用带 /EXPORTS 选项的 Dumpbin 工具,可以查看 DLL 的导出表。


有两种从 DLL 导出函数的方法:


在生成 DLL 时,创建一个模块定义 (.def) 文件并使用该 .def 文件。如果希望按序号而不是按名称从 DLL 导出函数,则请使用此方法。


在函数的定义中使用 __declspec(dllexport) 关键字。


用上述任何方法导出函数时,确保使用 __stdcall 调用约定。






-----------------------------Unicode 编程摘要-----------------------------------------
若要利用 MFC 和 C 运行时对 Unicode 的支持,需要:


定义 _UNICODE。


在生成程序之前定义 _UNICODE 符号。


指定入口点。


在项目的属性页对话框的“链接器”文件夹的“输出”页中,设置 wWinMainCRTStartup 的“入口点”符号。


使用可移植的运行时函数和类型。


为 Unicode 字符串处理使用正确的 C 运行时函数。可以使用 wcs 函数族,但您可能更喜欢使用完全可移植的(支持国际化的)_TCHAR 宏。这些宏都以 _tcs 为前缀;它们一对一地替换 str 函数族。在“运行时库参考”的国际化节中对这些函数有详细介绍。有关更多信息,请参见 Tchar.h 中的一般文本映射。


使用支持 Unicode 中描述的 _TCHAR 和相关的可移植数据类型。


正确地处理字符串。


Visual C++ 编译器将编码的字符串解释为:


  复制代码 
L"this is a literal string"
 


指出这是 Unicode 字符的字符串。可以对文字字符使用相同的前缀。一般使用 _T 宏对字符串进行编码,因此在 Unicode 下字符串编译为 Unicode 字符串,不使用 Unicode 时字符串编译为 ANSI 字符串(包括 MBCS)。例如,不要使用:


  复制代码 
pWnd->SetWindowText( "Hello" );
 


而使用: 


  复制代码 
pWnd->SetWindowText( _T("Hello") );
 


使用已定义的 _UNICODE,_T 将字符串翻译为以 L 为前缀的格式;否则 _T 将字符串翻译为不带 L 前缀的格式。


提示: 
_T 宏与 _TEXT 宏相同。
 


将字符串长度传递给函数时要小心。


一些函数需要获取字符串的字符数;另一些函数需要获取字符串的字节数。例如,如果已定义 _UNICODE,则下列对 CArchive 对象的调用无效(str 属于 CString):


  复制代码 
archive.Write( str, str.GetLength( ) );    // invalid
 


在 Unicode 应用程序中,由于每个字符都是 2 个字节宽,因此长度给出的是字符数而不是正确的字节数。所以必须使用:


  复制代码 
archive.Write( str, str.GetLength( ) * sizeof( _TCHAR ) );    // valid
 


它指定要写入的正确字节数。


但是,MFC 成员函数是面向字符而非面向字节的,因此无需此额外的编码:


  复制代码 
pDC->TextOut( str, str.GetLength( ) );
 


CDC::TextOut 采用字符数而非字节数。


使用 fopen_s, _wfopen_s 打开 Unicode 文件。


总之,MFC 和运行时库对 Windows 2000 下的 Unicode 编程提供下列支持:


除数据库类成员函数外,所有 MFC 函数(包括 CString)都支持 Unicode。CString 还提供 Unicode/ANSI 转换函数。


运行时库提供所有字符串处理函数的 Unicode 版本。(运行时库还提供适合 Unicode 或 MBCS 的可移植版本。这些版本是 _tcs 宏。)


Tchar.h 提供可移植的数据类型以及用于转换字符串和字符的 _T 宏。有关更多信息,请参见 Tchar.h 中的一般文本映射。


运行时库提供 main 的宽字符版本。使用 wmain 可使应用程序成为 Unicode 识别的应用程序。




示例一小段代码:
#include <tchar.h>
#include <Windows.h>


int _tmain(int argc, _TCHAR* argv[])
{
_TCHAR str[MAX_PATH] = { 0 };
GetCurrentDirectory(MAX_PATH, str);
_tprintf(_TEXT("%s"), str);


_tprintf("\n");


GetSystemDirectory(str, MAX_PATH);
_tprintf(_TEXT("%s"), str);
getchar();
return 0;
}




----------------------------如何:在各种字符串类型之间进行转换------------------------------------------
本主题演示如何将各种 Visual C++ 字符串类型转换为其他字符串。可以转换的字符串类型包括 char *、wchar_t*、_bstr_t、CComBSTR、CString、basic_string 和 System..::.String。在所有情况下,在将字符串转换为新类型时,都会创建字符串的副本。对新字符串进行的任何更改都不会影响原始字符串,反之亦然。


示例
说明
此示例演示如何从 char * 转换为上面列出的其他字符串类型。


代码
  复制代码 
// convert_from_char.cpp
// compile with: /clr /link comsuppw.lib


#include <iostream>
#include <stdlib.h>
#include <string>


#include "atlbase.h"
#include "atlstr.h"
#include "comutil.h"


using namespace std;
using namespace System;


int main()
{
    char *orig = "Hello, World!";
    cout << orig << " (char *)" << endl;


    // Convert to a wchar_t*
    size_t origsize = strlen(orig) + 1;
    const size_t newsize = 100;
    size_t convertedChars = 0;
    wchar_t wcstring[newsize];
    mbstowcs_s(&convertedChars, wcstring, origsize, orig, _TRUNCATE);
    wcscat_s(wcstring, L" (wchar_t *)");
    wcout << wcstring << endl;


    // Convert to a _bstr_t
    _bstr_t bstrt(orig);
    bstrt += " (_bstr_t)";
    cout << bstrt << endl;


    // Convert to a CComBSTR
    CComBSTR ccombstr(orig);
    if (ccombstr.Append(L" (CComBSTR)") == S_OK)
    {
        CW2A printstr(ccombstr);
        cout << printstr << endl;
    }


    // Convert to a CString
    CString cstring(orig);
    cstring += " (CString)";
    cout << cstring << endl;


    // Convert to a basic_string
    string basicstring(orig);
    basicstring += " (basic_string)";
    cout << basicstring << endl;


    // Convert to a System::String
    String ^systemstring = gcnew String(orig);
    systemstring += " (System::String)";
    Console::WriteLine("{0}", systemstring);
    delete systemstring;
}
 


输出
  复制代码 
Hello, World! (char *)
Hello, World! (wchar_t *)
Hello, World! (_bstr_t)
Hello, World! (CComBSTR)
Hello, World! (CString)
Hello, World! (basic_string)
Hello, World! (System::String)
 


示例
说明
此示例演示如何从 wchar_t * 转换为上面列出的其他字符串类型。


代码
  复制代码 
// convert_from_wchar_t.cpp
// compile with: /clr /link comsuppw.lib


#include <iostream>
#include <stdlib.h>
#include <string>


#include "atlbase.h"
#include "atlstr.h"
#include "comutil.h"


using namespace std;
using namespace System;


int main()
{
    wchar_t *orig = L"Hello, World!";
    wcout << orig << L" (wchar_t *)" << endl;


    // Convert to a char*
    size_t origsize = wcslen(orig) + 1;
    const size_t newsize = 100;
    size_t convertedChars = 0;
    char nstring[newsize];
    wcstombs_s(&convertedChars, nstring, origsize, orig, _TRUNCATE);
    strcat_s(nstring, " (char *)");
    cout << nstring << endl;


    // Convert to a _bstr_t
    _bstr_t bstrt(orig);
    bstrt += " (_bstr_t)";
    cout << bstrt << endl;


    // Convert to a CComBSTR
    CComBSTR ccombstr(orig);
    if (ccombstr.Append(L" (CComBSTR)") == S_OK)
    {
        CW2A printstr(ccombstr);
        cout << printstr << endl;
    }


    // Convert to a CString
    CString cstring(orig);
    cstring += " (CString)";
    cout << cstring << endl;


    // Convert to a basic_string
    wstring basicstring(orig);
    basicstring += L" (basic_string)";
    wcout << basicstring << endl;


    // Convert to a System::String
    String ^systemstring = gcnew String(orig);
    systemstring += " (System::String)";
    Console::WriteLine("{0}", systemstring);
    delete systemstring;
}
 


输出
  复制代码 
Hello, World! (wchar_t *)
Hello, World! (char *)
Hello, World! (_bstr_t)
Hello, World! (CComBSTR)
Hello, World! (CString)
Hello, World! (basic_string)
Hello, World! (System::String)
 


示例
说明
此示例演示如何从 _bstr_t 转换为上面列出的其他字符串类型。


代码
  复制代码 
// convert_from_bstr_t.cpp
// compile with: /clr /link comsuppw.lib


#include <iostream>
#include <stdlib.h>
#include <string>


#include "atlbase.h"
#include "atlstr.h"
#include "comutil.h"


using namespace std;
using namespace System;


int main()
{
    _bstr_t orig("Hello, World!");
    wcout << orig << " (_bstr_t)" << endl;


    // Convert to a char*
    const size_t newsize = 100;
    char nstring[newsize];
    strcpy_s(nstring, (char *)orig);
    strcat_s(nstring, " (char *)");
    cout << nstring << endl;


    // Convert to a wchar_t*
    wchar_t wcstring[newsize];
    wcscpy_s(wcstring, (wchar_t *)orig);
    wcscat_s(wcstring, L" (wchar_t *)");
    wcout << wcstring << endl;


    // Convert to a CComBSTR
    CComBSTR ccombstr((char *)orig);
    if (ccombstr.Append(L" (CComBSTR)") == S_OK)
    {
        CW2A printstr(ccombstr);
        cout << printstr << endl;
    }


    // Convert to a CString
    CString cstring((char *)orig);
    cstring += " (CString)";
    cout << cstring << endl;


    // Convert to a basic_string
    string basicstring((char *)orig);
    basicstring += " (basic_string)";
    cout << basicstring << endl;


    // Convert to a System::String
    String ^systemstring = gcnew String((char *)orig);
    systemstring += " (System::String)";
    Console::WriteLine("{0}", systemstring);
    delete systemstring;
}
 


输出
  复制代码 
Hello, World! (_bstr_t)
Hello, World! (char *)
Hello, World! (wchar_t *)
Hello, World! (CComBSTR)
Hello, World! (CString)
Hello, World! (basic_string)
Hello, World! (System::String)
 


示例
说明
此示例演示如何从 CComBSTR 转换为上面列出的其他字符串类型。


代码
  复制代码 
// convert_from_ccombstr.cpp
// compile with: /clr /link comsuppw.lib


#include <iostream>
#include <stdlib.h>
#include <string>


#include "atlbase.h"
#include "atlstr.h"
#include "comutil.h"
#include "vcclr.h"


using namespace std;
using namespace System;
using namespace System::Runtime::InteropServices;


int main()
{
    CComBSTR orig("Hello, World!");
    CW2A printstr(orig);
    cout << printstr << " (CComBSTR)" << endl;


    // Convert to a char*
    const size_t newsize = 100;
    char nstring[newsize];
    CW2A tmpstr1(orig);
    strcpy_s(nstring, tmpstr1);
    strcat_s(nstring, " (char *)");
    cout << nstring << endl;


    // Convert to a wchar_t*
    wchar_t wcstring[newsize];
    wcscpy_s(wcstring, orig);
    wcscat_s(wcstring, L" (wchar_t *)");
    wcout << wcstring << endl;


    // Convert to a _bstr_t
    _bstr_t bstrt(orig);
    bstrt += " (_bstr_t)";
    cout << bstrt << endl;


    // Convert to a CString
    CString cstring(orig);
    cstring += " (CString)";
    cout << cstring << endl;


    // Convert to a basic_string
    wstring basicstring(orig);
    basicstring += L" (basic_string)";
    wcout << basicstring << endl;


    // Convert to a System::String
    String ^systemstring = gcnew String(orig);
    systemstring += " (System::String)";
    Console::WriteLine("{0}", systemstring);
    delete systemstring;
}
 


输出
  复制代码 
Hello, World! (CComBSTR)
Hello, World! (char *)
Hello, World! (wchar_t *)
Hello, World! (_bstr_t)
Hello, World! (CString)
Hello, World! (basic_string)
Hello, World! (System::String)
 


示例
说明
此示例演示如何从 CString 转换为上面列出的其他字符串类型。


代码
  复制代码 
// convert_from_cstring.cpp
// compile with: /clr /link comsuppw.lib


#include <iostream>
#include <stdlib.h>
#include <string>


#include "atlbase.h"
#include "atlstr.h"
#include "comutil.h"


using namespace std;
using namespace System;


int main()
{
    CString orig("Hello, World!");
    wcout << orig << " (CString)" << endl;


    // Convert to a char*
    const size_t newsize = 100;
    char nstring[newsize];
    strcpy_s(nstring, orig);
    strcat_s(nstring, " (char *)");
    cout << nstring << endl;


    // Convert to a wchar_t*
    // You must first convert to a char * for this to work.
    size_t origsize = strlen(orig) + 1;
    size_t convertedChars = 0;
    wchar_t wcstring[newsize];
    mbstowcs_s(&convertedChars, wcstring, origsize, orig, _TRUNCATE);
    wcscat_s(wcstring, L" (wchar_t *)");
    wcout << wcstring << endl;


    // Convert to a _bstr_t
    _bstr_t bstrt(orig);
    bstrt += " (_bstr_t)";
    cout << bstrt << endl;


    // Convert to a CComBSTR
    CComBSTR ccombstr(orig);
    if (ccombstr.Append(L" (CComBSTR)") == S_OK)
    {
        CW2A printstr(ccombstr);
        cout << printstr << endl;
    }


    // Convert to a basic_string
    string basicstring(orig);
    basicstring += " (basic_string)";
    cout << basicstring << endl;


    // Convert to a System::String
    String ^systemstring = gcnew String(orig);
    systemstring += " (System::String)";
    Console::WriteLine("{0}", systemstring);
    delete systemstring;
}
 


输出
  复制代码 
Hello, World! (CString)
Hello, World! (char *)
Hello, World! (wchar_t *)
Hello, World! (_bstr_t)
Hello, World! (CComBSTR)
Hello, World! (basic_string)
Hello, World! (System::String)
 


示例
说明
此示例演示如何从 basic_string 转换为上面列出的其他字符串类型。


代码
  复制代码 
// convert_from_basic_string.cpp
// compile with: /clr /link comsuppw.lib


#include <iostream>
#include <stdlib.h>
#include <string>


#include "atlbase.h"
#include "atlstr.h"
#include "comutil.h"


using namespace std;
using namespace System;


int main()
{
    string orig("Hello, World!");
    cout << orig << " (basic_string)" << endl;


    // Convert to a char*
    const size_t newsize = 100;
    char nstring[newsize];
    strcpy_s(nstring, orig.c_str());
    strcat_s(nstring, " (char *)");
    cout << nstring << endl;


    // Convert to a wchar_t*
    // You must first convert to a char * for this to work.
    size_t origsize = strlen(orig.c_str()) + 1;
    size_t convertedChars = 0;
    wchar_t wcstring[newsize];
    mbstowcs_s(&convertedChars, wcstring, origsize, orig.c_str(), _TRUNCATE);
    wcscat_s(wcstring, L" (wchar_t *)");
    wcout << wcstring << endl;


    // Convert to a _bstr_t
    _bstr_t bstrt(orig.c_str());
    bstrt += " (_bstr_t)";
    cout << bstrt << endl;


    // Convert to a CComBSTR
    CComBSTR ccombstr(orig.c_str());
    if (ccombstr.Append(L" (CComBSTR)") == S_OK)
    {
        CW2A printstr(ccombstr);
        cout << printstr << endl;
    }


    // Convert to a CString
    CString cstring(orig.c_str());
    cstring += " (CString)";
    cout << cstring << endl;


    // Convert to a System::String
    String ^systemstring = gcnew String(orig.c_str());
    systemstring += " (System::String)";
    Console::WriteLine("{0}", systemstring);
    delete systemstring;
}
 


输出
  复制代码 
Hello, World! (basic_string)
Hello, World! (char *)
Hello, World! (wchar_t *)
Hello, World! (_bstr_t)
Hello, World! (CComBSTR)
Hello, World! (CString)
Hello, World! (System::String)
 


示例
说明
此示例演示如何从 System..::.String 转换为上面列出的其他字符串类型。


代码
  复制代码 
// convert_from_system_string.cpp
// compile with: /clr /link comsuppw.lib


#include <iostream>
#include <stdlib.h>
#include <string>


#include "atlbase.h"
#include "atlstr.h"
#include "comutil.h"
#include "vcclr.h"


using namespace std;
using namespace System;
using namespace System::Runtime::InteropServices;


int main()
{
    String ^orig = gcnew String("Hello, World!");
    Console::WriteLine("{0} (System::String)", orig);


    pin_ptr<const wchar_t> wch = PtrToStringChars(orig);


    // Convert to a char*
    size_t origsize = wcslen(wch) + 1;
    const size_t newsize = 100;
    size_t convertedChars = 0;
    char nstring[newsize];
    wcstombs_s(&convertedChars, nstring, origsize, wch, _TRUNCATE);
    strcat_s(nstring, " (char *)");
    cout << nstring << endl;


    // Convert to a wchar_t*
    wchar_t wcstring[newsize];
    wcscpy_s(wcstring, wch);
    wcscat_s(wcstring, L" (wchar_t *)");
    wcout << wcstring << endl;


    // Convert to a _bstr_t
    _bstr_t bstrt(wch);
    bstrt += " (_bstr_t)";
    cout << bstrt << endl;


    // Convert to a CComBSTR
    CComBSTR ccombstr(wch);
    if (ccombstr.Append(L" (CComBSTR)") == S_OK)
    {
        CW2A printstr(ccombstr);
        cout << printstr << endl;
    }


    // Convert to a CString
    CString cstring(wch);
    cstring += " (CString)";
    cout << cstring << endl;


    // Convert to a basic_string
    wstring basicstring(wch);
    basicstring += L" (basic_string)";
    wcout << basicstring << endl;


    delete orig;
}
 


输出
  复制代码 
Hello, World! (System::String)
Hello, World! (char *)
Hello, World! (wchar_t *)
Hello, World! (_bstr_t)
Hello, World! (CComBSTR)
Hello, World! (CString)
Hello, World! (basic_string)
 


---------------------------用于生成命令和属性的宏-------------------------------------------
可以在项目的“属性页”对话框中任何接受字符串的位置使用这些宏。这些宏不区分大小写。



 说明
 
$(RemoteMachine) 
 设置为“调试”属性页上“远程计算机”属性的值。有关更多信息,请参见更改用于 C/C++ 调试配置的项目设置。
 
$(References) 
 以分号分隔的引用列表被添加到项目中。
 
$(ConfigurationName) 
 当前项目配置的名称(例如“Debug”)。
 
$(PlatformName) 
 当前项目平台的名称(例如“Win32”)。
 
$(Inherit) 
 指定在由项目生成系统所撰写的命令行中,继承的属性出现的顺序。默认情况下,继承的属性出现在当前属性的末尾。
 
$(NoInherit) 
 使任何将被继承的属性不被继承。若还要避免同级级别的计算,请使用 $(StopEvaluating)。使用 $(NoInherit) 会导致对于同一属性忽略任何出现的 $(Inherit)。
 
$(StopEvaluating) 
 立即停止计算链中宏的计算。 出现在 $(StopEvaluating) 之后的任何值将不出现在宏的计算值中。 如果 $(StopEvaluating) 在 $(Inherit) 之前,计算链中当前位置的继承值将不会连接到宏值。 $(StopEvaluating) 是 $(NoInherit) 的功能超集。
 
$(ParentName) 
 包含此项目项的项的名称。该名称将是父文件夹名称或项目名称。
 
$(RootNameSpace) 
 包含应用程序的命名空间(如果有)。
 
$(IntDir) 
 为中间文件指定的相对于项目目录的目录路径。它解析为“中间目录”属性的值。
 
$(OutDir) 
 输出文件目录的路径,相对于项目目录。这解析为“输出目录”属性的值。
 
$(DevEnvDir) 
 Visual Studio .NET 的安装目录(定义形式:驱动器 + 路径);包括尾部的反斜杠“\”。
 
$(InputDir) 
 输入文件的目录(定义形式:驱动器 + 路径);包括尾部的反斜杠“\”。如果该项目是输入,则此宏等效于 $(ProjectDir)。
 
$(InputPath) 
 输入文件的绝对路径名(定义形式:驱动器 + 路径 + 基本名称 + 文件扩展名)。如果该项目是输入,则此宏等效于 $(ProjectPath)。
 
$(InputName) 
 输入文件的基本名称。如果该项目是输入,则此宏等效于 $(ProjectName)。
 
$(InputFileName) 
 输入文件的文件名(定义为基本名称 + 文件扩展名)。如果该项目是输入,则此宏等效于 $(ProjectFileName)。
 
$(InputExt) 
 输入文件的文件扩展名。它包括文件扩展名前面的“.”。如果该项目是输入,则此宏等效于 $(ProjectExt)。
 
$(ProjectDir) 
 项目的目录(定义形式:驱动器 + 路径);包括尾部的反斜杠“\”。
 
$(ProjectPath) 
 项目的绝对路径名(定义形式:驱动器 + 路径 + 基本名称 + 文件扩展名)。
 
$(ProjectName) 
 项目的基本名称。
 
$(ProjectFileName) 
 项目的文件名(定义为基本名称 + 文件扩展名)。
 
$(ProjectExt) 
 项目的文件扩展名。它包括文件扩展名前面的“.”。
 
$(SolutionDir) 
 解决方案的目录(定义形式:驱动器 + 路径);包括尾部的反斜杠“\”。
 
$(SolutionPath) 
 解决方案的绝对路径名(定义形式:驱动器 + 路径 + 基本名称 + 文件扩展名)。
 
$(SolutionName) 
 解决方案的基本名称。
 
$(SolutionFileName) 
 解决方案的文件名(定义为基本名称 + 文件扩展名)。
 
$(SolutionExt) 
 解决方案的文件扩展名。它包括文件扩展名前面的“.”。
 
$(TargetDir) 
 生成的主输出文件的目录(定义形式:驱动器 + 路径);包括尾部的反斜杠“\”。
 
$(TargetPath) 
 生成的主输出文件的绝对路径名(定义形式:驱动器 + 路径 + 基本名称 + 文件扩展名)。
 
$(TargetName) 
 生成的主输出文件的基本名称。
 
$(TargetFileName) 
 生成的主输出文件的文件名(定义为基本名称 + 文件扩展名)。
 
$(TargetExt) 
 生成的主输出文件的文件扩展名。它包括文件扩展名前面的“.”。
 
$(VSInstallDir) 
 安装 Visual Studio .NET 的目录。
 
$(VCInstallDir) 
 安装 Visual C++ .NET 的目录。
 
$(FrameworkDir) 
 安装 .NET Framework 的目录。
 
$(FrameworkVersion) 
 Visual Studio 使用的 .NET Framework 版本。与 $(FrameworkDir) 相结合,就是 Visual Studio 使用的 .NET Framework 版本的完整路径。
 
$(FrameworkSDKDir) 
 安装 .NET Framework 的目录。.NET Framework 可作为 Visual Studio .NET 的一部分安装,也可单独安装。
 
$(WebDeployPath) 
 从 Web 部署根到项目输出所属于的位置的相对路径。返回与 RelativePath 相同的值。
 
$(WebDeployRoot) 
 指向 <localhost> 位置的绝对路径。例如,c:\inetpub\wwwroot。
 
$(SafeParentName) 
 有效名称格式的直接父级的名称。例如,窗体是 .resx 文件的父级。
 
$(SafeInputName) 
 作为有效类名的文件的名称,但不包括文件扩展名。
 
$(SafeRootNamespace) 
 项目向导将在其中添加代码的命名空间名称。此命名空间名称将只包含在有效的 C++ 标识符中允许的字符。
 
$(FxCopDir) 
 fxcop.cmd 文件的路径。fxcop.cmd 文件不和所有的 Visual C++ 版本一起安装。
 


1. 使用属性的命令行属性页查看如何继承属性。有关属性继承的更多信息,请参见用属性页指定项目设置。有关用法示例,请参见使用 $(Inherit) 和 $(NoInherit)。


请参见
概念
在 Visual Studio 中生成 C++ 项目




----------------------MSDN帮助文档中关于MIDL学习笔记------------------------------------------
Each procedure declaration must contain a procedure name, return type, and parameter list.
(每一个过程声明都必须包含过程名称、返回值类型和参数列表)




All parameters in the remote procedure declarations must be declared as [in], [out], or [in,out]. 
(所有的参数在远程过程中声明必须指定[in], [out], 或者 [in,out],主要是为了说明客户端服务端是取数据
还是拿数据)




术语:Microsoft? Interface Definition Language (MIDL)




客户端的只是用来检索参数用的,检索到的参数会以一种网络数据格式来进行
传给服务端程序,真正的执行是在服务端。
----------------------------------------------------------------------
----------------------------------------------------------------------
----------------------------------------------------------------------
----------------------------------------------------------------------
----------------------------------------------------------------------
----------------------------------------------------------------------
----------------------------------------------------------------------
----------------------------------------------------------------------
----------------------------------------------------------------------
----------------------------------------------------------------------
----------------------------------------------------------------------
----------------------------------------------------------------------
----------------------------------------------------------------------
----------------------------------------------------------------------
----------------------------------------------------------------------
----------------------------------------------------------------------
----------------------------------------------------------------------
----------------------------------------------------------------------
----------------------------------------------------------------------
----------------------------------------------------------------------
----------------------------------------------------------------------
----------------------------------------------------------------------
----------------------------------------------------------------------
----------------------------------------------------------------------
----------------------------------------------------------------------
----------------------------------------------------------------------
----------------------------------------------------------------------
----------------------------------------------------------------------


 
 
 
 
 
 
 
发布了172 篇原创文章 · 获赞 132 · 访问量 189万+

猜你喜欢

转载自blog.csdn.net/cosmoslife/article/details/9842015