问题标签 [low-level]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
delphi - 低级键盘钩子问题:应用程序未聚焦时键盘状态丢失(Delphi)
我被要求开发一个可以与现有应用程序一起工作的新应用程序。两个应用程序都将等待条形码阅读器输入。我不希望我们的操作员扫描条形码两次:一次用于现有应用程序(16 位 - 剪裁器,无源),一次用于新应用程序。为了解决这个问题,我决定使用低级键盘挂钩(用 Delphi 编写)。它看起来很完美,因为 2 个应用程序需要条形码阅读器输入,而且我的应用程序大部分时间都不会集中注意力。
当我的应用程序聚焦时,我的低级键盘钩子运行良好。例如,如果我进入 TEdit 控件,然后扫描我的条形码:
- 等待的字符将显示在 TEdit 控件中 (#02;90BDIJ#)。
- 低级挂钩将获取所有字符(#,然后是 0,然后是 2,依此类推)。
当我的应用程序不再专注时,情况会变得更糟:如果我打开记事本然后扫描我的条形码:
- 等待的字符将显示在记事本中 (#02;90BDIJ#)。
- 低级钩子会出错字符:“àé;çàbdij”
看起来键盘状态没有考虑在内!似乎不再考虑 Shift、Ctrl 甚至 Alt 键。在我的法语键盘上:
- '#' = CTRL = ALT + "
- '0' = SHIFT + à
- '2' = SHIFT + é
- ...
有谁现在如何解决这个问题?我做错了吗(我应该改用 Windows 消息吗?)。先感谢您。
FWIW 这是我的源代码:
c - 跨平台 VM 的 C 内存管理
我问了一个关于C 型尺寸的问题,我得到了一个很好的答案,但我意识到我可能无法很好地表述这个问题以对我的目的有用。
在转到软件工程师之前,我的背景是计算机工程师,所以我喜欢计算机体系结构,并且一直在考虑制作 VM。我刚刚完成了一个在 Java 上制作 VM 的有趣项目,对此我感到非常自豪。但是有一些法律问题我现在不能开源它,我目前有一些空闲时间。所以我想看看我是否可以在 C 上制作另一个 VM(速度更快),只是为了好玩和教育。
问题是我不是 C 程序,上一次我写一个非琐碎的 C 问题是在 10 多年前。我是 Pascal、Delphi,现在是 Java 和 PHP 程序员。
我可以预见到许多障碍,我正在努力解决一个障碍,那就是访问现有的库(在 Java 中,反射解决了这个问题)。
我计划通过数据缓冲区(类似于堆栈)来解决这个问题。我的 VM 的客户端可以在给我指向本机函数的指针之前将数据放入这些堆栈中。
本机函数的推送、拉取和调用可以由字节码触发(这就是稍后制作 VM 的方式)。
为了完整起见(以便您可以在您的机器上尝试),这里是 Stack 的代码:
在本机功能方面,我创建了以下用于测试目的:
p>执行时,上面的代码返回:
这在我的机器上运行良好(Linux x86 32bits GCC-C99)。如果这也适用于其他操作系统/架构,那就太好了。但是我们必须注意至少三个与内存相关的问题。
1)。数据大小 - 如果我在相同架构上使用相同的编译器编译 VM 和本机函数,大小类型应该是相同的。
2)。字节序 - 与数据大小相同。
3)。内存对齐 - 这是一个问题,因为填充字节可能会添加到结构中,但是在准备参数堆栈时很难同步它(除了硬编码之外,没有办法知道如何添加填充)。
我的问题是:
1)。如果我知道类型的大小,有没有办法修改推拉功能以与结构填充完全同步?(修改为让编译器像 Datasize 和 Endians 问题一样处理它)。
2)。如果我按一个(使用#pragma pack(1)
)打包结构;(2.1) 性能损失是否可以接受?(2.2) 项目稳定性是否会受到威胁?
3)。填充 2,4 或 8 怎么样?哪个适合一般的 32 位或 64 位系统?
4)。您能否指导我查看有关 x86 上 GCC 的精确填充算法的文档?
5)。有没有更好的方法?
注意:跨平台不是我的最终目标,但我无法抗拒。此外,只要性能不那么难看,性能就不是我的目标。所有这些都是为了娱乐和学习。
对不起我的英语和很长的帖子。
提前感谢大家。
c - 内联汇编器:可以使用哪些暂存器?
在使用类 C 语言将内联汇编器插入函数时,关于允许将哪些寄存器用于临时的约定是什么?asm
在进入块之前保存它需要保存的所有寄存器的值是编译器的责任吗?程序员是否有责任将这些寄存器中的值存储在某个地方并在退出asm
块之前恢复它们?是否有一个典型的约定,或者这是非常特定于实现的?
.net - .NET 程序集中“~”元数据标头中排序位向量字段的用途是什么?
根据分区 II 元数据,它说有效字段是一个位掩码,它记录了 .NET 可执行文件中存在哪些 CLR 元数据表——但我不知道“排序”字段的用途是什么——它的意义是什么?在创建自己的 .NET 可移植可执行映像时,我应该向该字段发出什么信息?
winapi - 我可以将 LowLevelMouseProc 和 LowLevelKeyboardProc 放在主 EXE 中吗?
全局 Windows 挂钩必须在 DLL 中,因为挂钩将在不同进程的上下文中调用,因此挂钩过程的代码必须注入该进程。但是,有一些限制:
SetWindowsHookEx
可用于将 DLL 注入另一个进程。32位DLL不能注入64位进程,64位DLL不能注入32位进程。如果一个应用程序需要在其他进程中使用钩子,则需要一个 32 位应用程序调用SetWindowsHookEx
将一个 32 位 DLL 注入 32 位进程,一个 64 位应用程序调用SetWindowsHookEx
将一个 64 位 DLL 注入64 位进程。32 位和 64 位 DLL 必须具有不同的名称。
出于这个原因,我宁愿使用低级钩子WH_MOUSE_LL
and WH_KEYBOARD_LL
,而不是WH_MOUSE
and WH_KEYBOARD
。从他们的 文档中可以看出:
这个钩子在安装它的线程的上下文中被调用。通过向安装钩子的线程发送消息来进行调用。因此,安装钩子的线程必须有一个消息循环。
这使我认为这些特定的钩子程序不需要位于单独的 DLL 中,而可以直接存在于连接它们的 EXE 中。但是,文档SetWindowsHookEx
说:
lpfn
[in] 指向钩子程序的指针。如果
dwThreadId
参数为零或指定由不同进程创建的线程的标识符,则该lpfn
参数必须指向 DLL 中的挂钩过程。
没有提到两个低级挂钩的明确例外。
我见过几个使用低级钩子的 .NET 应用程序,它们的钩子过程没有放在单独的 DLL 中。这是另一个暗示这是可以接受的。但是,由于文档禁止这样做,我自己有点害怕这样做。
如果我不使用 DLL 并且只是将这些低级挂钩程序直接放入我的 EXE 中,是否有人预见到任何麻烦?
编辑:对于赏金,我想要一个明确的“是的,这没关系,因为......”或“不,这可能会出错,因为......”。
performance - 在 D 语言中比较两个内存块的最有效方法是什么?
我需要一个内存块的比较函数,以便在 D 编程语言中对字节数组进行二进制搜索。它不需要任何有用的语义。它只需要快速并且是有效的比较函数(产生总排序的函数)。已知要比较的内存块具有相同的长度。
Cmemcmp
实际上很慢,因为它试图保留有用的字符串比较语义,而我不需要。以下是迄今为止我想出的最好的。有没有人知道更好的东西,最好不要浸入非便携式 CPU 特定指令?
编辑:我已经阅读了 SSE,我不想使用它有 3 个原因:
- 它不是便携式的。
- 它需要在 ASM 中编程。
- 比较说明假定您的数据是浮点数,如果某些数据恰好与 NaN 的模式匹配,这可能会出现问题。
java - 分配延迟似乎很高,为什么?
我有一个在低延迟环境中运行的(java)应用程序,它通常处理约 600 微秒(+/- 100)的指令。自然地,随着我们进一步进入微秒空间,您会看到成本延迟发生变化的事情,现在我们注意到 2/3 的时间花在了 2 个核心域对象的分配上。
基准测试已将有问题的代码部分从现有引用中分离出来,即从字面上构建对象,即基本上是大量引用(每个类中约 15 个)和几个新列表,尽管请参阅下面的注释以了解准确测量的内容这里。
每个人始终需要〜100micros,这对我来说是莫名其妙的,我正试图找出原因。一个快速的基准测试表明,一个类似大小的充满字符串的对象大约需要 2-3 微秒才能新建,显然这种基准测试充满了困难,但认为它可能作为基准有用。
这里有2个Q
- 如何调查这种行为?
- 分配缓慢有什么解释?
请注意,所涉及的硬件是 Sun X4600 上的 Solaris 10 x86,具有 8 个双核 opterons @ 3.2GHz
我们看过的东西包括
- 检查 PrintTLAB 统计信息,显示 v 几个缓慢的分配,所以那里不应该有争用。
- PrintCompilation 表明其中一段代码不是 JIT 友好的,尽管 Solaris 在这里似乎有一些不寻常的行为(即与现代 linux 相比,现在没有与 solaris10 类似的老式 linux 可供使用)
- 日志编译...至少可以说有点难以解析,所以这是一项持续的工作,到目前为止还没有什么明显的
- JVM 版本... 6u6 和 6u14 一致,尚未尝试 6u18 或最新 7
任何和所有想法表示赞赏
对各种帖子的评论摘要,以尝试使事情更清晰
- 我正在测量的成本是创建通过 Builder(如其中之一)构建的对象的总成本,其私有构造函数调用 new ArrayList 几次以及设置对现有对象的引用。测量的成本包括设置构建器和将构建器转换为域对象的成本
- 编译(通过热点)有显着的影响,但它仍然相对较慢(在这种情况下,编译将其从 100 微秒降至约 60 微秒)
- 在我的幼稚基准上编译(通过热点)将分配时间从 ~2micros 减少到 ~300ns
- 延迟不随年轻一代收集算法(ParNew 或并行清除)而变化
performance - 在 D 中实现低级库的建议(相对于 C/C++)
我需要一些关于为项目选择 D 编程语言的建议。该项目是一个低级库,类似于具有许多关联容器等的数据库。因此,效率对我来说非常重要。
我需要为该库提供一个 C API,以便与 C++ 和 Python 等其他语言兼容,并且我还预计某些部分可能需要用纯 C 编写以调整性能。
D 似乎对这份工作很有吸引力:考虑到这些要求,我应该注意哪些陷阱?D 容器的性能与 std::(map, vector, unordered_map, etc...) 相比如何,考虑到手动性能调整(例如使用 std::map::lower_bound 进行搜索/插入等)。
algorithm - 需要装配编程帮助 (TASM) - 布斯算法
我编写了一个算法来模拟布斯算法,只使用加、减和逻辑运算符并返回一个十六进制值。我的 Tasm 编译器不断向我抛出这些错误。当我尝试修改代码时,它仍然不起作用。有人可以帮帮我吗?
(29) 行上的额外字符
(38) 非法立即数
(44) 非法立即
数 (52) 下划线符号:RES2
(126) 期望指针类型