2014-01-05 37 views
0

我對CodeBlocks 12.11附帶的MinGW的發行版本沒有任何問題。但現在我試圖編譯SyncSys。編譯enet是沒有問題的,但用gcc/MinGW編譯SyncSys會帶來錯誤,我不能使用函數_InterlockedOr8,因爲它沒有聲明。研究導致_interlockedOr8在intrin.h中定義。 intrin.h不包括在內,我在MinGW/gcc:x86intrin.h上搜索它的等價物。但這仍然行不通。 InterlockedOr8將是要調用的「真實」函數,但編譯器無法找到這個函數,儘管包含了winbase.h和windows.h。gcc上的InterlockedOr8 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風格。

更新

下面是OR操作之前正確返回目的地地址內的原始值的版本。它也許可以使用一些代碼審查審查...

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,如果我在代碼塊設置編譯器MSVC10我沒有調試器和cl.exe總是拋出D8003-錯誤。我從來沒有看過彙編程序,因此我不知道代碼中發生了什麼,所以如果您可以添加一些提示/註釋並感謝您的幫助,那將會很酷。 – JoshuaBehrens

+0

我也看了一下代碼,你是對的,它不關心返回值,但_InterlockedAnd8必須返回正確的值,因爲它被使用。我只是猜測_InterlockedAnd8的代碼必須是: void _InterlockedAnd8(volatile char * dst,char src){asm(「mov eax,dst; mov cl,src; lock and [eax],cl;」); } 我對嗎? – JoshuaBehrens

+0

或多或少。但是,如果代碼實際上使用了InterlockedOr8的返回值(這是交換之前dst指向的值),則生成的彙編代碼變得更多一些,並使用互鎖比較交換調用。 – selbie