#define CANCEL_COMMON_DIALOG_HOOK(name) \
void __declspec(naked) ##name##CancelCommonDialogHook(void) \
{ \
__asm \
{ \
add esp, [k##name##CancelCommonDialogStackOffset] \
jz RESTORE \
jmp [k##name##CancelCommonDialogNewFileRetnAddr] \
RESTORE: \
pushad \
call DoSavePluginCommonDialogHook \
test eax, eax \
jnz REMOVE \
popad \
jmp [k##name##CancelCommonDialogRestoreRetnAddr] \
REMOVE: \
popad \
jmp [k##name##CancelCommonDialogRemoveRetnAddr] \
} \
}
使用上面的宏会导致编译器抛出此错误:
错误C2400:内联汇编语法 '第二操作数'中的错误;发现 '恢复'
我做错了什么?
编辑:
void __declspec(naked) #name##CancelCommonDialogHook(void) \
{ \
__asm add esp, [k##name##CancelCommonDialogStackOffset] \
__asm jz RESTORE \
__asm jmp [k##name##CancelCommonDialogNewFileRetnAddr] \
RESTORE: \
__asm pushad \
__asm call DoSavePluginCommonDialogHook \
__asm test eax, eax \
__asm jnz REMOVE \
__asm popad \
__asm jmp [k##name##CancelCommonDialogRestoreRetnAddr] \
REMOVE: \
__asm popad \
__asm jmp [k##name##CancelCommonDialogRemoveRetnAddr] \
}
以上代码也不起作用:
错误C2447:'{':缺少功能 header(旧式正式列表?)错误 C2014:必须启动预处理程序命令 作为第一个非白色空间
答案 0 :(得分:0)
至少在我最后一次尝试时,你无法在VC ++中的内联汇编块中创建标签。使用C风格的标签虽然有效:
void __declspec(naked) ##name##CancelCommonDialogHook(void) \
{ \
__asm \
{ \
add esp, [k##name##CancelCommonDialogStackOffset] \
jz RESTORE \
jmp [k##name##CancelCommonDialogNewFileRetnAddr] \
} \
RESTORE: \
_asm { \
pushad \
call DoSavePluginCommonDialogHook \
test eax, eax \
jnz REMOVE \
popad \
jmp [k##name##CancelCommonDialogRestoreRetnAddr] \
} \
REMOVE: \
__asm { \
popad \
jmp [k##name##CancelCommonDialogRemoveRetnAddr] \
} \
}
我还没有在VC ++中编写任何内联汇编很长一段时间,所以我不能保证它会起作用,但我猜这是一个非常公平的机会。
答案 1 :(得分:0)
我一直没有电脑访问权限,所以希望你已经解决了这个问题。我认为问题是使用“\”来结束该行实际上告诉C预处理器将下一行与该行合并。请参阅this page上的评论3和行拼接here。这适用于大多数C语句,但对于汇编更有问题,因为新行是它如何定义语句。
我可以想到解决方案的两种方法。首先是找到类似C的“;”可以在装配中用作法定分隔符,我不知道是否存在这样的东西。第二种方法是将所有内容包装在单独的__asm
语句中。采取第二种方法,如下:
void __declspec(naked) ##name##CancelCommonDialogHook(void)
{
__asm{add esp, [k##name##CancelCommonDialogStackOffset]} \
__asm{jz RESTORE} \
__asm{jmp [k##name##CancelCommonDialogNewFileRetnAddr]} \
RESTORE: \
__asm{pushad} \
__asm{call DoSavePluginCommonDialogHook} \
__asm{test eax, eax} \
__asm{jnz REMOVE} \
__asm{popad} \
__asm{jmp [k##name##CancelCommonDialogRestoreRetnAddr]} \
REMOVE: \
__asm{popad} \
__asm{jmp [k##name##CancelCommonDialogRemoveRetnAddr]} \
}
注意:我已将标签留在asm语句之外,因为:
__asm
块答案 2 :(得分:0)
只是一个疯狂的猜测:宏会将所有文本扩展为一行,最后是add esp, [k...] jz RESTORE jmp k...
。也许在每个汇编指令的末尾添加分号会很有帮助。
该假设的一个指示是错误发生在你的第二个“线”上。第一个是好的,但第二个将合并到第一个,所以这是编译器混淆的第一次机会。如果错误发生在某个地方,那可能不是这样。
答案 3 :(得分:0)
通过将函数体包含在另一个范围内来修复它。