Hungry Mind , Blog about everything in IT - C#, Java, C++, .NET, Windows, WinAPI, ...

Windows Server 2008 SDK and .NET 3.5

Прямой линк без всяких валидаций: Microsoft® Windows® Software Development Kit (SDK) for Windows Server® 2008 and .NET Framework 3.5!

Canadian Mind Products

Тяжело сказать что такое Canadian Mind Products. Энциклопедия что-ли?

Зато вот о Roedy Green’s Java & Internet Glossary можно сказать лишь одно - просто замечательнейший reference/documentation по Java. Пользуюсь часто и всем советую. Почти каждая страница содержит описание книжек по теме.

Visual Studio debugging tips

Visual Studio по функциональности и удобству заставляет курить в сторонке все IDE для плюсов. Но, некоторых мелочей, все же, очень не хватает. А иногда они просто хорошо спрятаны...

Довольно часто приходится вставлять куски кода вида hr = GetLastError();, запускать Error Lookup чтобы прочитать человеческим языком что же произошло. Я уже давно пользуюсь одним из более удобных способов:

  1. Если статический тип переменной - HRESULT, то окошки дебаггера Visual Studio (Watch #, Autos, Locals etc) автоматически отображают в колонке Value строку ошибки вместо кода.
  2. Псевдопеременная err или @err отображает текущее числовое значение GetLastError(). А для отображения строки вместо числа нужно применить форматирование - добавить через запятую hr. Пример: @err,hr.

    Visual Studio поддерживает множество форматов. Подробнее - Visual Studio Debugger --> Format Specifiers in C++

  3. При вызове COM-метода возвращаемое значение HRESULT попадает в регистр eax, поэтому @eax,hr расскажет нам в чем беда.

Есть и другие псевдопеременные - $handles, $vframe, $TID, $ENV, $CMDLINE, @registername или $registername, $clk, $user. Приятно, а?

JVM Hosting

Хостинг усправляемого кода в программных продуктах уже не редкость. Oracle поддерживает выполнение байткода JVM еще с 8-й версии и периодически выполняет апгрейд виртуальной машины (11g поставляется с версией 1.5). Сравнительно недавно добавили поддержку .NET 1.1 и .NET 2.0. Microsoft SQL Server 2005 имеет поддержку CLR 2.0 и, кстати, внутренняя архитектура последнего была усовершенствована (скорее заточена) под задачи хостинга. Дальше я расскажу, как добавить возможность выполнять JVM-код в приложение, написанное на С++.

Подготовка проекта для хостинга виртуальной машины Java.

Первое, что необходимо сделать, - поставить Java Development Kit версии 6. Далее в настройках проекта прописать папку поиска заголовочных файлов JDK - "C:\Program Files\Java\jdk1.6.0_03\include\", папку с библиотечными файлами - "C:\Program Files\Java\jdk1.6.0_03\lib" и добавить путь поиска jvm.dll - C:\Program Files\Java\jdk1.6.0_03\jre\bin\client\ как написано здесь. Еще нужно закинуть файл "c:\Program Files\Java\jdk1.6.0_03\include\win32\jni_md.h" в папку с проектом и включить его в проект. Традиционно изменяем stdafx.h:

#include <jni.h>
#pragma comment(lib, "jvm.lib")

Инициализация виртуальной машины Java.

Перед использованием, виртуальную машину Java необходимо загрузить и инициализировать. По-сути, она является песочницей (sandbox) для выполняемого байт-кода, другими словами, мини-операционной системой в пределах хост-процесса. Инициализация предполагает создание управляющих структур, выделение пулов памяти и других ресурсов ОС, связанных с конкретным екземпляром JVM (да, их можно создать несколько).

jint jRet;

JavaVMOption options[1];
options[0].optionString = "-verbose:class,gc,jni";

JavaVMInitArgs jvmInitArgs;
jvmInitArgs.version = JNI_VERSION_1_6;
jvmInitArgs.nOptions = _countof(options);
jvmInitArgs.options = options;
jvmInitArgs.ignoreUnrecognized = JNI_TRUE;

JavaVM *pJvm;
JNIEnv *pEnv;
jRet = JNI_CreateJavaVM(&pJvm, reinterpret_cast<LPVOID*>(&pEnv), &jvmInitArgs);
if (jRet != JNI_OK) {
   // Это залет, солдат!
   cout << "JNI_CreateJavaVM returned " << jRet << endl;
   return(jRet);
}

Структура JavaVMInitArgs содержит настройки создания екземпляра JVM - запрашиваемую версию и различные конфигурационные параметры. Функция JNI_CreateJavaVM, как нетрудно догадаться из ее названия, создает виртуальную машину и возвращает указатель на управляющий интерфейс - JNIEnv. Любые дальнейшие манипуляции выполняются посредством него.

Выполнение байт-кода JVM.

Не буду оригинален. Вашему вниманию представляется вариант "Hello World" в исполнении C++/Java:

void printHelloWorld(JNIEnv *pEnv) {
   jclass classSystem = pEnv->FindClass("java/lang/System");
   jfieldID fieldId = pEnv->GetStaticFieldID(classSystem, "out", "Ljava/io/PrintStream;");
   jobject system_out = pEnv->GetStaticObjectField(classSystem, fieldId);

   jclass classPrintStream = pEnv->FindClass("java/io/PrintStream");
   jmethodID methodId = pEnv->GetMethodID(classPrintStream, "println", "(Ljava/lang/String;)V");

   jvalue v;
   v.l = pEnv->NewStringUTF("Hello World!");
   pEnv->CallVoidMethodA(system_out, methodId, &v);
   if (jthrowable ex = pEnv->ExceptionOccurred()) {
      pEnv->ExceptionDescribe();
      pEnv->ExceptionClear();
   }
}

Завершение работы.

По завершению работы с JVM рантайм нужно удалить:

jRet = pJvm->DestroyJavaVM();
if (jRet != JNI_OK) {
   cout << "pJvm->DestroyJavaVM() returned " << jRet << endl;
   return(jRet);
}

Google new autocomplete

Google new autocomplete
Copyright 2007-2011 Chabster