#define связанный запрос - PullRequest
0 голосов
/ 12 марта 2012

Я занимался переносом кода с Linux на Windows. Я использую среду Visual Studio. Я застрял с одной проблемой.

В Windows есть вызов функции с 2 параметрами для получения и освобождения семафора. Код Linux имеет один параметр
Окна:

KeInitializeSpinLock(spinlock,oldIRQL);

Linux

spin_lock_init(spinlock);

У меня есть общий вызов, который я должен использовать:

Get_Lock(spinlock);

Как мне сделать это для Windows без изменения прототипа Get_Lock?

Я попробовал следующее:

#define Get_Lock(lock) \

KIRQL  oldIrql;\

KeAcquireSpinLock(&(lock),&oldIrql);

#define Release_Lock(sync) KeReleaseSpinLock(&(sync),oldIrql)

Но компилятор выдает ошибки .. В основном я хочу сохранить значение oldIrql, потому что это значение необходимо для KeReleaseSpinLock

Error

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?

Ответы [ 2 ]

1 голос
/ 12 марта 2012

Проблема связана с тем, что компилятор Microsoft поддерживает только стандарт C89, который не допускает смешения кода и объявлений. Get_Lock() вызывается после строки кода (я подозреваю), которая вводит объявление oldIrql.

Если это так, что блокировка получается и освобождается в одной и той же области видимости, всегда возможное исправление (хак) было бы объявить KIRQL oldIrql; в верхней части области, где вызывается Get_Lock() и Release_Lock(), и удалите объявление из 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 голосов
/ 12 марта 2012

Я также подозреваю причину, опубликованную 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 .Вы можете сослаться на то же самое.

...