2012-03-12 67 views
0

我正在做代碼從Linux移植到Windows。我正在使用Visual Studio環境。我陷入了一個問題。#define related Query

有一個函數調用2個參數用於獲取和釋放Windows中的信號量。 Linux的代碼有一個參數
的Windows:

KeInitializeSpinLock(spinlock,oldIRQL); 

的Linux

spin_lock_init(spinlock); 

我有通用的調用,比如,我不得不使用:

Get_Lock(spinlock); 

如何做到這一點的窗戶不改變原型Get_Lock

我試過如下:

#define Get_Lock(lock) \ 

KIRQL oldIrql;\ 

KeAcquireSpinLock(&(lock),&oldIrql); 

#define Release_Lock(sync) KeReleaseSpinLock(&(sync),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 
該值保留 oldIrql

KIRQL定義爲

typedef UCHAR KIRQL 

我在這裏做什麼錯?還是有沒有其他方法可以在不改變Get_LockRelease_Lock的原型的情況下使用?

+0

編譯器給你的版本有什麼錯誤? – 2012-03-12 14:40:27

+2

大概錯誤是當'Release_Lock'被調用時'oldIrql'未定義?作爲'Get_Lock()',其中'oldIrql'被聲明,不一定在調用'Release_Lock()'的同一個作用域中被調用。 – hmjd 2012-03-12 14:46:41

+0

我檢查過的範圍是一樣的 – 2012-03-12 14:47:46

回答

1

問題是由於Microsoft編譯器的唯一支持C89標準,它不允許混合代碼和聲明。 Get_Lock()正在一行代碼後面調用(我懷疑),它引入了oldIrql的聲明。

如果它是該鎖獲得並在相同的範圍內總是可能的修復(劈)釋放將是在其中Get_Lock()Release_Lock()被稱爲範圍的頂部,以聲明KIRQL oldIrql;,並刪除從聲明的情況下Get_Lock()

更簡單的解決方案是消除宏並引入定義鎖的新的struct。例如:

typedef struct _lock 
{ 
#ifdef WIN32 
    UCHAR  oldIrql; 
    PKSPIN_LOCK sem; 
#else 
#endif 
} lock; 

lock* lock_new() 
{ 
    lock* result = malloc(sizeof(lock)); 

    /* Perform OS dependent initialisation. */ 
#ifdef WIN32 
#else 
#endif 
    return result; 
} 

void lock_delete(lock* aLock) 
{ 
    /* Perform OS dependent tidy tasks. */ 
#ifdef WIN32 
#else 
#endif 
    free(aLock); 
} 

void lock_obtain(lock* aLock) 
{ 
    /* OS dependent acquire. */ 
#ifdef WIN32 
    KeAcquireSpinLock(&aLock->sem, &aLock->oldIrql); 
#else 
#endif 
} 

void lock_release(lock* aLock) 
{ 
    /* OS dependent release. */ 
#ifdef WIN32 
    KeReleaseSpinLock(&aLock->sem, aLock->oldIrql); 
#else 
#endif 
} 
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大致相同。你也可以參考一樣。