2013-08-07 3 views
1

Я программист на Java, Python, пытающийся возиться с C++. У меня следующий фрагмент кода -Почему GCC не компилирует этот код?

#include <windows.h> 

bool IsInsideVMWare() 
{ 
    bool rc = true; 

    __try 
    { 
    __asm 
    { 
     push edx 
     push ecx 
     push ebx 

     mov eax, 'VMXh' 
     mov ebx, 0 // any value but not the MAGIC VALUE 
     mov ecx, 10 // get VMWare version 
     mov edx, 'VX' // port number 

     in  eax, dx // read port 
        // on return EAX returns the VERSION 
     cmp ebx, 'VMXh' // is it a reply from VMWare? 
     setz [rc] // set return value 

     pop ebx 
     pop ecx 
     pop edx 
    } 
    } 
    __except(EXCEPTION_EXECUTE_HANDLER) 
    { 
    rc = false; 
    } 

    return rc; 
} 

я получаю следующие компиляции ошибки -

__try' undeclared (first use this function) __except»необъявленную (сначала использовать эту функцию)

Что это расплывчатое сообщение даже означает? Поскольку попытка не объявлена, я должен сначала попробовать ее использовать?

Edit:

IDE - Codeblocks

Compiler - GCC

+4

Какой у вас компилятор? Поскольку эти «ключевые слова» являются [расширением] (http://msdn.microsoft.com/en-us/library/zazxh1a9.aspx) строк компиляторов C на Visual C++, никакой другой компилятор, о котором я знаю, их не знаю. Также обратите внимание, что они являются расширениями языка программирования ** C ** и не предназначены для использования в программах на C++. –

+0

Это неопределенное сообщение означает, что ваш компилятор считает, что __try является переменной, и вы ее не объявляли. Я не эксперт в области C++, но не стоит пытаться просто «попробовать» вместо «__try»? Не знаю, как это исправить, но может указать вам в правильном направлении. – caiocpricci2

+1

это означает «первое использование в этой функции» – fuenfundachtzig

ответ

6

Этот код относится к конкретным функциям Microsoft __try и __except. Другого способа решения этого не существует, так как выполнение инструкции IN в режиме пользовательского режима в Windows обычно прерывается. В VMWare любая такая операция перехватывается VMWare VMM (Virtual Machine Monitor, иногда также называемым Hypervisor). Затем он проверяет специальные значения в некоторых регистрах и «принимает» инструкцию с новым значением в ebx, чтобы указать, что «Да, я - система VMWare».Если вы запустите это на простой старой системе Windows, он получит общую защиту, чтобы попытаться использовать IO-порт, недоступный для приложения [в общем случае, порты ввода-вывода недоступны для приложения пользовательского режима код].

Вам необходимо скомпилировать это с помощью компилятора Microsoft (и с подходящим флажком «Включить обработку исключений» - извините, не помню, что это за флаг, но он скажет вам, не ошибается ли это) , GCC не поддерживает эту функцию.

Однако вы можете протестировать VMWare, используя инструкцию CPUID, вместо использования IN. Это будет работать намного лучше в компиляторе GCC, так как это не вызовет ошибки процессора, если нет присутствия VM [Для педантов: до тех пор, пока процессор будет позже, чем версия 486 с 1990-х годов). Вместо этого он просто не даст правильные значения в регистрах (без изменения значений регистра). Возможно, вам понадобится написать встроенную функцию ассемблера , но это не должно быть слишком сложно для google.

Смотрите эту KB-статья на сайте VMwares: http://kb.vmware.com/selfservice/microsites/search.do?language=en_US&cmd=displayKC&externalId=1009458

В качестве альтернативы, если вы действительно настаиваете на использование Windows, структурированной обработки исключений, вы можете сделать это самостоятельно:

push handler // Save address of your handler. 
    push fs:[0] // Save address of any previous handler 
    mov fs:[0], esp // Save pointer to current exception record. 

    ... // all the stuff setting registers, doing IN, etc. 

    jmp cleanup 

handler: 
    mov [rc], 0  // Set "rc= false". 

cleanup: 
    pop fs:[0] 
    add esp, 4 // Remove handler 

(Примечание, я просто написал, что из-за немного googling - это долгое время, так как я использовал что-то подобное в Windows, поэтому он может не работать)

1

Символы __try и __except являются необъявленная, компилятор не в состоянии решить их.
Вы должны прочитать документацию своего компилятора об использовании таких ключевых слов (если они вообще выйдут).
C++ дает try и catch ключевые слова для этой цели, попробуйте

bool IsInsideVMWare() 
{ 
    bool rc = true; 

    try 
    { 
    __asm 
    { 
     ... 
    } 
    } 
    catch(...) //catch all possible exceptions 
    { 
    rc = false; 
    } 

    return rc; 
} 

Помните, однако, что C++ не имеет глубоких выполнения, как сделать Python или Java! Таким образом, существует только несколько исключений времени выполнения.

Маленькая статья от MSDN.

+3

За исключением того, что ТОЛЬКО работает, если у вас есть что-то, что переводит исключение машинной инструкции в исключение типа C++, и я сомневаюсь, что оно существует. –

+0

Согласен! Я не верю, что для этого есть большой шанс. Просто я использовал '...', чтобы не указывать особый тип ecxeption. –

1

Не исключены ли исключения C++ в блоках try {} catch {}? Обратитесь к http://www.cplusplus.com/doc/tutorial/exceptions/

Если вы используете __try, ваш компилятор C++, вероятно, подумает, что это функция, поэтому сообщение об ошибке.

или вы могли бы сделать #define __try попробовать макросы, возможно! :)

Кроме того, какой компилятор вы используете? Если вы используете GCC, я думаю, вам также может понадобиться исправить список clobberlist встроенной сборки, чтобы убедиться, что GCC не переопределяет его.

5

__try - вещь SEH. См предыдущие вопросы here и here
Я думаю, что вам нужно #include <excpt.h> для windows
сообщение «первое использование» означает, что это первый раз, когда вы использовали его.
try и catch разные, как поясняют ссылки.

+0

В том числе 'excpt.h' не работает. Есть ли другой способ заставить его работать, кроме компиляции его с помощью VC++? Я предполагаю, что MS должна обеспечить реализацию '__try' в некоторой библиотеке. Не могу я просто включить его и заставить его работать? –

+0

Я разместил ссылку в комментариях - вы используете gcc, и я сказал, что работал на окна. Почему вместо этого просто C++ пытается и поймать? – doctorlove

+0

Поскольку блок catch C++ не будет ловить исключения, созданные инструкциями по сборке. –

-1

Я не кодер, но я обошел это, просто определив их, прежде чем они вызванный.

определяют __try

определяют __except

хех вуаля работал. код, который я запускал, нуждался в другом ';' который, как сообщается, добавил, что он работает.

надеюсь, что это поможет, так как ничего другого я не видел. :)

+1

«#» перед определением явно! – Lex

+0

минус один, потому что: он просто предотвращает ошибку, кроме самого себя, но не решает проблему и делает гораздо больше ошибок. – Developer

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