procedure TForm2.Button1Click(Sender: TObject);
function EnumWindowsProc(Ahwnd: hwnd; AlParam: lParam): Boolean; stdcall;
begin
ShowMessage('hwnd:' + IntToStr(Ahwnd));
ShowMessage('lParam' + IntToStr(AlParam));
Result := True;
end;

begin
EnumChildWindows(0, @EnumWindowsProc, 123);
end;
代码就是上面这点,选择编译32位平台,123会被传送到LParam里,选择编译64位平台123会被传送到hwnd里,这是怎么回事?
IDE是XE6,是我不会用吗?
----------------------------------------------

function EnumWindowsProc(Ahwnd: hwnd; AlParam: lParam): Boolean; stdcall;
begin
ShowMessage('hwnd:' + IntToStr(Ahwnd));
ShowMessage('lParam' + IntToStr(AlParam));
Result := True;
end;

procedure TForm2.Button1Click(Sender: TObject);
begin
EnumChildWindows(0, @EnumWindowsProc, 123);
end;

这样既可.
因为你如果要用嵌套函数的话编译出来的和外边的函数是不同的.
嵌套函数编译后编译器会多给一个参数作为第一个参数.这个参数保存的是父函数的栈底.当父函数调用这个嵌套函数的时候32位会塞ebp,64位会塞rbp作为第一个参数进来.

之所以32位表现似乎是没问题,因为你是stdcall,32位的时候是用栈传递参数,那么当
EnumChildWindows调用到你的函数时,你的函数取的是栈顶的三个值,刚好后两个就是Ahwnd,AlParam.

而64位只有一种调用约定stdcall,而stdcall的参数是rcx,rdx,r8,r9传递前四个参数,后面用栈传.EnumChildWindows调用你的函数的时候只给了rcx,rdx两个值.而你的函数则认为应该是rcx,rdx,r8三个参数.那么你的123被EnumChildWindows当成第二个参数放在rdx中.而你的回调函数则认为自己有三个参数,rcx是编译器给的父函数的栈底,rdx是Ahwnd.

基本就是上面的情况.
----------------------

64位只有一种调用约定stdcall的更多相关文章

  1. 宏WINAPI和几种调用约定

    在VC SDK的WinDef.h中,宏WINAPI被定义为__stdcall,这是C语言中一种调用约定,常用的还有__cdecl和__fastcall.这些调用约定会对我们的代码产生什么样的影响?让我 ...

  2. 64位系统VBS调用32位COM组件

    64位系统VBS调用32位COM组件 标签: 32位, 64位, COM, COM组件, VB, VBS, VBScript 标题: 64位系统VBS调用32位COM组件作者: Demon链接: ht ...

  3. 64位进程调用32位dll的解决方法 / 程序64位化带来的问题和思考

    最近做在Windows XP X64,VS2005环境下做32位程序编译为64位程序的工作,遇到了一些64位编程中可能遇到的问题:如内联汇编(解决方法改为C/C++代码),long类型的变化,最关键的 ...

  4. 64位进程调用32位dll的解决方法

    64位进程调用32位dll的解决方法   最近做在Windows XP X64,VS2005环境下做32位程序编译为64位程序的工作,遇到了一些64位编程中可能遇到的问题:如内联汇编(解决方法改为C/ ...

  5. X86调用约定 calling convention

    http://zh.wikipedia.org/wiki/X86%E8%B0%83%E7%94%A8%E7%BA%A6%E5%AE%9A 这里描述了在x86芯片架构上的调用约定(calling con ...

  6. Wow64(32位进程)注入DLL到64位进程

    转载自: https://blog.poxiao.me/p/wow64-process-inject-dll-into-x64-process/ 向其他进程注入DLL通常的做法是通过调用CreateR ...

  7. 用VC进行64位编程

    用VC进行64位编程 分类: C/C++2014-04-30 15:14 532人阅读 评论(0) 收藏 举报 本文转自:http://www.usidcbbs.com/read-htm-tid-52 ...

  8. x86 x64下调用约定浅析

    x86平台下调用约定 我们都知道x86平台下常用的有三种调用约定,__cdecl.__stdcall.__fastcall.我们分别对这三种调用约定进行分析. __cdecl __cdecl是C/C+ ...

  9. [转]C#程序无法在64位系统上运行之.NET编译的目标平台

    今天将编译的C#的exe拷贝到测试机上(Win7_64bit),一运行就挂了,提示“stop working”,一开始怀疑测试机上没有安装.net framework框架,追究半天原来是编译的目标平台 ...

随机推荐

  1. .Net Core添加分布式Session

    一.Session HTTP是一个无状态协议,Web服务器将每一个请求都视为独立请求.并且不保存之前请求中用户的值. Session 状态是ASP.NET Core提供的一个功能,它可以在用户通应用访 ...

  2. C#设置开机启动项、取消开机启动项

    如果想你写的程序随系统开机一起启动的话,那么你可以照下面这个方法来做. RunWhenStart(false, Application.ProductName, Application.Startup ...

  3. js 获取属性名称,再根据这个属性名获取值

    if (result.success) { var obj = JSON.parse(result.data); var sltObj = document.getElementById(" ...

  4. Redis-RDB持久化设置

    1.如何配置RDB持久化机制redis.conf文件,也就是/etc/redis/6379.conf,去配置持久化 save 60 1000 每隔60s,如果有超过1000个key发生了变更,那么就生 ...

  5. luogu P1714 切蛋糕 单调队列

    单调队列傻题. 考虑以 $i$ 结尾的答案 : $max(sumv_{i}-sumv_{j}),j \in [i-m,i-1]$ ($sumv_{i}$ 为前缀和) 稍微搞一搞,发现 $sumv_{i ...

  6. 雪花算法生成全局唯一ID

    系统中某些场景少不了全局唯一ID的使用,来保证数据的唯一性.除了通过数据库自带的自增id来保证 id 的唯一性,通常为了保证的数据的可移植性会选择通过程序生成全局唯一 id.百度了不少php相关的生成 ...

  7. 七夕心形demo

    from turtle import * pensize(1) pencolor('red') fillcolor('pink') speed(5) up() goto(-30, 100) down( ...

  8. python第十一周:RabbitMQ、Redis

    Rabbit Mq消息队列 RabbitMQ能为你做些什么? 消息系统允许软件.应用相互连接和扩展.这些应用可以相互链接起来组成一个更大的应用,或者将用户设备和数据进行连接.消息系统通过将消息的发送和 ...

  9. 权值线段树&线段树合并

    权值线段树 所谓权值线段树,就是一种维护值而非下标的线段树,我个人倾向于称呼它为值域线段树. 举个栗子:对于一个给定的数组,普通线段树可以维护某个子数组中数的和,而权值线段树可以维护某个区间内数组元素 ...

  10. D2007在win7下bordbk105N.dll 莫名其妙的问题。

    已经装过一次win7下d2007.再装一次就出现许多莫名其妙的问题.其中之一: Windows 7 64bit Delphi Debugger Fix / Workaround 2013-08-28 ...