2014-01-05 3 views
0

У меня не было проблем с поставляемой версией MinGW, поставляемой с CodeBlocks 12.11. Но теперь я попытался скомпилировать SyncSys. Компиляция enet не была проблемой, но компиляция самой SyncSys с gcc/MinGW приносит ошибки, что я не могу использовать функцию _InterlockedOr8, потому что она не объявлена. Исследования приводят к тому, что _InterlockedOr8 определяется в intrin.h. intrin.h не входит, и я искал эквивалент для него на MinGW/gcc: x86intrin.h. Но это все еще не работает. InterlockedOr8 будет «реальной» функцией для вызова, но это невозможно найти ни компилятором, хотя включены winbase.h и windows.h.InterlockedOr8 на gcc MinGW

При исследовании этой проблемы там, где очень мало хитов, от которых я не мог учиться. Как я могу это исправить?

ответ

1

_InterlockedOr8 - встроенная функция компилятора, уникальная для компилятора Microsoft - это означает, что компилятор автоматически внедряет реализацию в код вместо связывания с библиотекой. <intr.h> - это файл заголовка, распространяемый вместе с Visual Studio, отдельно от Windows SDK.

Если вы не можете переключиться на Visual Studio (free download, btw), то вы можете определить свою собственную версию замены этой функции:

void InterlockedOr8(char* dst, char src) 
{ 
    __asm 
    { 
     mov eax, dst  ; EAX = dst 
     mov cl, src  ; ECX = src 
     lock or [eax], cl ; *dst = src | *dst; // this is the actual interlocked-or op 
    } 
} 

Обратите внимание, что эта функция отличается от _InterlockedOr8 в том, что она Безразлично» t вернуть исходное значение * dst. Реализация становится более сложной, если вам нужно вернуть значение. Я быстро взглянул на источник SyncSys. Два места, которые нуждаются в этой функции, не нуждаются в возвращаемом значении. Итак, все, что вам нужно сделать, это преобразовать приведенный выше код, чтобы использовать gcc-стиль встроенной сборки.

Update

Вот версия, которая правильно возвращает исходное значение в адресе назначения до операции ИЛИ. Это, вероятно, может использовать немного код обзора критики ...

char MyInterlockedOr8(char* dst, char src) 
{ 
    char result = 0; 
    const size_t ptr_size = sizeof(dst); 

    _asm 
    { 
     mov esi, dst ; esi = dst 
     mov cl, src  ; cl = src // keep "src" cached in a register 
     mov al, [esi] ; al = *dst 
start: 
     mov bl, cl  ; bl = src 
     or bl, al  ; bl = src | *dst 

     lock cmpxchg [esi], bl; // if (*dst == eax) { *dst=bl ;} else {al = *dst}; 
     jne start 

     mov result, al ; result = al 
    } 

    return result; 
} 
+0

Я мог бы перейти к VS, я VS уже установлен, но я не люблю IDE и если установить компилятор в CodeBlocks для MSVC10 У меня нет отладчика и cl.exe всегда выдает D8003-Ошибки. Я никогда не смотрел на ассемблер, поэтому я понятия не имею, что происходит в вашем коде, поэтому было бы здорово, если бы вы могли добавить некоторые подсказки/комментарии и спасибо за вашу помощь. – JoshuaBehrens

+0

Я также посмотрел на код, вы правы, что он не заботится о возвращаемом значении, но _InterlockedAnd8 должен вернуть правильное значение, потому что оно используется. Я просто догадался, что код для _InterlockedAnd8 должен быть: void _InterlockedAnd8 (volatile char * dst, char src) {asm ("mov eax, dst; mov cl, src; lock и [eax], cl;"); } Я прав? – JoshuaBehrens

+0

Более или менее. Но если код действительно использует возвращаемое значение из InterlockedOr8 (которое является значением, на которое указывает dst перед свопом), сгенерированный ассемблерный код становится немного больше и делает использование вызова с блокировкой-обменом обменом. – selbie

Смежные вопросы