У меня не было проблем с поставляемой версией 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 - это встроенная функция компилятора, уникальная для компилятора Microsoft - это означает, что компилятор автоматически внедряет реализацию в код вместо привязки к библиотеке. <intr.h>
- это файл заголовка, распространяемый вместе с Visual Studio, отдельно от Windows SDK.
Если вы не можете переключиться на Visual Studio (бесплатно скачать, 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 тем фактом, что она не возвращает исходное значение * dst. Реализация становится более сложной, если вам нужно вернуть значение. Я быстро взглянул на источник SyncSys. Два места, которые нуждаются в этой функции, не нуждаются в возвращаемом значении. Итак, все, что вам нужно сделать, это преобразовать приведенный выше код, чтобы использовать gcc-стиль встроенной сборки.
Обновить
Здесь версия, которая вернет исходное значение в целевом адресе перед операцией ИЛИ. Вероятно, он может использовать небольшой обзор проверки кода...
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;
}