我正在进行从Linux到Windows的代码移植。我正在使用Visual Studio环境。我遇到了一个问题。
在Windows中有一个带有2个参数的函数调用,用于获取和释放信号量。
Linux代码有一个参数
视窗:
KeInitializeSpinLock(spinlock,oldIRQL);
Linux的
spin_lock_init(spinlock);
我有通用电话,我必须使用:
Get_Lock(spinlock);
如何在不更改Get_Lock
原型的情况下为Windows执行此操作?
我尝试了以下内容:
#define Get_Lock(lock) \
KIRQL oldIrql;\
KeAcquireSpinLock(&(lock),&oldIrql);
#define Release_Lock(sync) KeReleaseSpinLock(&(sync),oldIrql)
但编译器发出错误。基本上我想保留oldIrql
的值,因为KeReleaseSpinLock
需要该值
错误
error C2275: 'KIRQL' : illegal use of this type as an expression
error C2146: syntax error : missing ';' before identifier 'oldIrql'
error C2065: 'oldIrql' : undeclared identifier
error C2065: 'oldIrql' : undeclared identifier
error C2065: 'oldIrql' : undeclared identifier
KIRQL
定义为
typedef UCHAR KIRQL
我在这里做错了什么?或者是否有其他方法可以在不更改Get_Lock
和Release_Lock
原型的情况下使用?
答案 0 :(得分:1)
问题是由于Microsoft编译器仅支持C89标准,它不允许混合代码和声明。 Get_Lock()
是在一行代码(我怀疑)之后被调用的,它引入了oldIrql
的声明。
如果是在同一范围内获取和释放锁的情况,则可能的修复(hack)是在KIRQL oldIrql;
和{{范围的顶部声明Get_Lock()
。调用1}},并从Release_Lock()
删除声明。
更整洁的解决方案是消除宏并引入一个定义锁的新Get_Lock()
。例如:
struct
答案 1 :(得分:0)
我也怀疑hmjd发布的原因。但是,在我看来,解决方案可以如下:
#define Get_Lock(lock) { KIRQL oldIrql; KeAcquireSpinLock(&(lock),&oldIrql);
#define Release_Lock(sync) KeReleaseSpinLock(&(sync),oldIrql) }
但是,你需要确保Get_Lock&根据您的意见,Release_Lock与您保证的范围相同。
这个想法与pthread_cleanup_push & pthread_cleanup_pop的想法大致相同。您也可以参考相同的内容。