我正在创建自定义键盘布局。作为开始步骤,我想让用户按下一个键,让我的键盘钩子拦截它,并输出我选择的不同键。
我找到了这个键盘钩子代码,为了我的目的,我试图稍微修改它:http : //blogs.msdn.com/toub/archive/2006/05/03/589423.aspx
我已将相关方法更改为:
private static IntPtr HookCallback(int nCode, IntPtr wParam, IntPtr lParam)
{
if (nCode >= 0 && wParam == (IntPtr)WM_KEYDOWN)
{
KBDLLHOOKSTRUCT replacementKey = new KBDLLHOOKSTRUCT();
Marshal.PtrToStructure(lParam, replacementKey);
replacementKey.vkCode = 90; // char 'Z'
Marshal.StructureToPtr(replacementKey, lParam, true);
}
return CallNextHookEx(_hookID, nCode, wParam, lParam);
}
Run Code Online (Sandbox Code Playgroud)
我希望它声明一个新的 KBD 结构对象,将键盘钩子提供的 KBD 结构复制到其中,修改对象的 vkCode 以使用不同的字符,然后用修改后的版本覆盖提供的对象。这应该有希望保持所有内容相同,除了它写入不同的字符这一事实。
不幸的是,它不起作用。键入原始键盘字符。Visual Studio 输出窗格也会A first chance exception of type 'System.ArgumentException' occurred in MirrorBoard.exe出错。
我可以在这里做什么来拦截键盘钩子并用我选择的字符替换它?
谢谢!
我偶然发现了一篇关于Xor 链表的维基百科文章,这是一个有趣的琐事,但该文章似乎暗示它偶尔会在实际代码中使用。我很好奇它有什么用处,因为我不明白为什么它即使在内存/缓存严重受限的系统中也有意义:
考虑到上述情况,有什么意义呢?是否存在任何奇怪的极端情况,异或链接列表实际上是值得的?
我已经了解到,在 x86-64 平台上使用任何 64 位寄存器都需要一个REX前缀,而任何小于 64 位的地址都需要一个地址大小前缀。
在 x86-64 位上:
E3rel8 是jrcxz
67 E3rel8 是jecxz
67是地址大小覆盖前缀的操作码。
sizeof(int_fast8_t)是 8 位,而其他sizeof(int_fast16_t)和sizeof(int_fast32_t)(仅在 Linux 上)是 64 位。
为什么其他快速类型定义是 64 位而只有int_fast8_t8 位?
和对齐有关系吗?
我是一名Web开发人员,主要从事Ruby和C#...
我想学习一门低级语言,所以我看起来不像我(计算机科学专家)老板面前的屁股.
我听过很多纯粹的嗡嗡声,关于汇编语言是如何学习计算机实际工作的唯一方法,但另一方面,C语言可能更有用,而不仅仅是理论.
所以我的问题是......
学习C会教我足够的计算机科学理论/低级编程,看起来不像一个普通的花花公子(完整工具)吗?
谢谢!
丹尼尔
多谢你们!
一些非常好的答案,
我想我会学习C只是为了掌握内存管理,但我认为你的权利,我会更好地学习更多我使用的语言!
我想知道一些高级语言的低级功能.在我的脑海中,我可以指出:-bitwise operations -bit fields -pointer arithmetic -inline assembly -interrupt functions
如果你指出一些不在我的清单中,我会赞成的.如果C或Pascal拥有它们会很好,但基本上任何高级语言都可以.谢谢.
众所周知,用于乘法的处理器指令所需的时间比加法多几倍,除法甚至更差(UPD:不再适用,见下文).那些更复杂的操作如指数呢?他们有多难?
动机.我感兴趣,因为它有助于算法设计在早期阶段估计算法的性能关键部分.假设我想对图像应用一组过滤器.其中一个在每个像素的3×3邻域上运行,将它们相加并取得atan.另一个相加较多的相邻像素,但不使用复杂的功能.哪一个会执行更长时间?
因此,理想情况下我希望具有基本操作执行的近似相对时间,例如乘法通常需要比加法多5倍的时间,指数大约是100次乘法.当然,这是一个数量级的协议,而不是确切的值.我知道它取决于硬件和参数,所以我们说我们测量现代x86/x64上浮点运算的平均时间(在某种意义上).对于未在硬件中实现的操作,我对C++标准库的典型运行时间感兴趣.
在分析这样的事情时,您是否看过任何消息来源?这个问题有意义吗?或者没有像这样的经验法则可以在实践中应用?
我开始学习Assembly(ASM x86).我正在使用模拟器emu8086.我写了以下说明:
mov eax,3
Run Code Online (Sandbox Code Playgroud)
当我试图模仿指令时,emu8086写道: wrong parameters MOV eax,3. probably it's an undefined var: eax
此外,当我换成eax用ax,ah或al-它的工作就好了.
为什么会那样?我该怎么做才能解决这个问题?谢谢.
如果我有struct,例如:
#[derive(Clone, Copy)]
#[repr(C, packed)]
pub struct SomeData {
a: u16,
b: u64,
c: u32,
d: u16,
}
Run Code Online (Sandbox Code Playgroud)
如何将其复制到内存中的特定位置,例如0x1000有效地复制到内存中的某个位置?会这样的吗?
let dst_addr: u64 = 0x1000;
let src = SomeData {a: 1, b: 2, c: 3, d: 4};
unsafe {
let tmp: &[u8; 10] = transmute(src);
copy(dst_addr as *mut _, tmp);
}
Run Code Online (Sandbox Code Playgroud)
请注意,repr(C, packed)这里实际需要这部分.
该软件在裸x86_64,ring 0上运行,没有操作系统或其他限制.另外,我在没有标准库的情况下进行编程,因此只有core库才能实现这一点.
这当然是不安全的,但这不是问题.
编辑:只是澄清:我正在复制到未初始化的内存.
我需要比较一个字符串,作为参数传递给WinDbg与来自内存的字符串.怎么能实现这一目标?
例如,字符串位于加载的PE内的特定偏移量中.所以,我可以通过执行轻松读取字符串da /c 100 <addr>.但是,如何使用此字符串arg1,在WinDbg脚本中使用.if?(而且$SPAT(),我猜)
我试图将da命令的输出读入别名或用户定义的寄存器,但我没有成功.
假设2个内核试图在相同的时刻(正负eta)将不同的值写入相同的RAM地址(1个字节),并且不使用任何互锁指令或内存屏障.在这种情况下会发生什么以及将什么值写入主RAM?第一个获胜?最后一个获胜?不确定的行为?