2014-01-05 39 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