пятница, 23 июля 2010 г.
четверг, 22 июля 2010 г.
ALL For ESXi =))
http://blog.vmpros.nl/2010/07/15/vmware-failed-to-read-the-upgrade-package-metadata-xml-upgrading-to-esxi-4-1/
http://wiki.contribs.org/VMware_Tools
пятница, 9 июля 2010 г.
modal : bool
This property holds whether show() should pop up the dialog as modal or modeless.
By default, this property is false and show() pops up the dialog as modeless. Setting his property to true is equivalent to setting QWidget::windowModality to Qt::ApplicationModal.
exec() ignores the value of this property and always pops up the dialog as modal.
Access functions:
bool isModal () const
void setModal ( bool modal )
See also QWidget::windowModality, show(), and exec().
dll.h Код C++ (Qt)
class TestClass
{
public:
void func();
};
Dll.cpp Код C++ (Qt)
#include "dll.h"
#include
void TestClass::func()
{
std::cout << "Call func()" << std::endl;
}
extern "C" TestClass *buildClass()
{
return new TestClass;
}
Собераешь как dll.
А дальше, все как ты делал, загрузил dll, получил указатель на функцию buildClass. С ее помощью создаются объекты. Интерфейс описан в dll.h
source
Привязать виртуальные порты к портам реальным. Например чтобы оставить ИПТв только на одном порту, к которому подключена приставка, например на 4-м, а интернет на всех остальных (в случае наличия 4-х портов)
Запускаем телнет и вводим следующие команды:
sys tri port enable
sys tri port groupadd 1 LAN 1 2 3 PVC 1 WLAN
sys tri port groupadd 2 LAN 4 PVC 3
sys tri igmp enable
sys tri port save
После этого коннект по WiFi становится стабильным, но но на качество ИпТв это не влияет..
http://forum.grodno.net/index.php?topic=33681.0;all
среда, 7 июля 2010 г.
Раздел: Программирование >> C/C++
Использование интерфейсов при работе с DLL
Как вы, наверное, знаете, в динамически подключаемых библиотеках (DLL) используются соглашения языка C при объявлении экспортируемых объектов, в то время как в C++ применяется несколько иная система генерации имен при компиляции, так что нельзя просто экспортировать функции - методы класса С++ и затем использовать их в коде приложения-клиента (здесь и далее под клиентом подразумевается приложение, использующее DLL). Однако это можно сделать при помощи интерфейсов, доступных и DLL, и клиентскому приложению. Этот метод очень мощный и в то же время элегантный, т.к. клиент видит только абстрактный интерфейс, а фактический класс, который реализует все функции может быть любым. Microsoft'овская технология COM (Component Object Model) построена на подобной идее (плюс дополнительная функциональность, конечно). В этой статье будет рассказано, как использовать "классовый" подход с применением интерфеса, похожего на COM, при раннем (на этапе компиляции) и позднем (во время работы программы) связывании.
Если вы хоть раз работали с DLL, то уже знаете, что DLL имееет особенную функцию DllMain(). Эта функция подобна WinMain, или main() в том смысле, что это своего рода точка входа в DLL. Операционная система автоматически вызывает эту функцию в случаае, если DLL загружается и выгружается. Обычно эту функцию ни для чего другого не используют.
Существует два метода подключения DLL к проекту - это раннее (на этапе компиляции программы) и позднее (во время выполнения программы) связывание. Методы различаются способом загрузки DLL и способом вызова функций, реализованных и экспортированных из DLL.
Раннее связывание (во время компиляции программы)
При таком методе связывания операционная система автоматически загружает DLL во время запуска программы. Однако требуется, чтобы в разрабатываемый проект был включен .lib файл (библиотечный файл), соответствующий данной DLL. Этот файл определяет все экспортируемые объекты DLL. Объявления могут содержать обычные функции C или классы. Все, что нужно клиенту - использовать этот .lib файл и включить заголовочный файл DLL - и ОС автоматически загрузит эту DLL. Как видно, этот метод выглядит очень простым в использовании, т.к. все прозрачно. Однако вы должны были заметить, что код клиента нуждается в перекомпиляции всякий раз, когда изменяется код DLL и, соответственно, генерируется новый .lib файл. Удобно ли это для вашего приложения - решать вам. DLL может объявить функции, которые она хочет экспортировать, двумя методами. Стандартный метод - использование .def файлов. Такой .def файл - это просто листинг функций, экспортируемых из DLL.
//============================================================
// .def файл
LIBRARY myfirstdll.dll
DESCRIPTION 'My first DLL'
EXPORTS
MyFunction
//============================================================
// заголовок DLL, который будет включен в код клиента
bool MyFunction(int parms);
//============================================================
// реализация функции в DLL
bool MyFunction(int parms)
{
// делаем все, что нужно
............
}
Я думаю, можно не говорить, что в данном примере экспортируется только одна функция MyFunction. Второй метод объявления экспортируемых объектов специфичен, но намного мощнее: вы можете экспортировать не только функции, но также классы и переменные. Давайте посмотрим на на фрагмент кода, сгенерированный при создании DLL AppWizard'ом VisualC++. Комментариев, включенных в листинг, вполне хватает, чтобы понять , как все это работает.
//============================================================
// Заголовок DLL, который должен быть включен в код клиента
/*
Следующий блок ifdef - стандартный метод создания макроса,
который далает экспорт из DLL проще. Все файлы этой DLL
компилируются с определенным ключом MYFIRSTDLL_EXPORTS.
Этот ключ не определяется для любого из проектов, использующих эту DLL.
Таким образом, любой проект, в который включен это файл, видит функции
MYFIRSTDLL_API как импортируемые из DLL, тогда как сама DLL
эти же функции видит как экспортируемые.
*/
#ifdef MYFIRSTDLL_EXPORTS
#define MYFIRSTDLL_API __declspec(dllexport)
#else
#define MYFIRSTDLL_API __declspec(dllimport)
#endif
// Класс экспортируется из test2.dll
class MYFIRSTDLL_API CMyFirstDll {
public:
CMyFirstDll(void);
// TODO: здесь можно добавить свои методы.
};
extern MYFIRSTDLL_API int nMyFirstDll;
MYFIRSTDLL_API int fnMyFunction(void);
Во время компиляции DLL определен ключ MYFIRSTDLL_EXPORTS, поэтому перед объявлениями экспортируемых объектов подставляется ключевое слово __declspec(dllexport). А когда компилируется код клиента, этот ключ неопределен и перед объектами появляется префикс __declspec(dllimport), так что клиент знает, какие объекты импортируются из DLL.
В обоих случаях все, что нужно сделать клиенту - добавить файл myfirstdll.lib в проект и включить заголовочный файл, который объявляет импортируемые из DLL объекты, а затем использовать эти объекты (функции, классы и переменные) точно так же, как будто они были определены и реализованы локально в проекте. А теперь давайте разберем другой метод использования DLL, который чаще бывает удобнее и мощнее.
Позднее связывание (во время работы программы)
Когда используется позднее связывание, DLL загружается не автоматически, при запуске программы, а напрямую в коде, там, где это нужно. Не нужно использовать никакие .lib файлы, так что клиентское приложение не требует перекомпиляции при изменении DLL. Такое связывание обладает мощными возможностями именно потому, что ВЫ решаете, когда и какую DLL загрузить. Например, вы пишете игру, в которой используется DirectX и OpenGL. Вы можете просто включить весь необходимый код в исполняемый файл, но тогда разобраться в чем-нибудь будет просто невозможно. Или можно поместить код DirectX в одну DLL, а код OpenGL - в другую и статически подключить их к проекту. Но теперь весь код взаимнозависим, так что если вы написали новую DLL, содержащую код DirectX, то перекомпилировать придется и исполняемый файл. Единственным удобством будет то, что вам не нужно заботиться о загрузке (хотя неизвестно, удобство ли это, если вы загружаете обе DLL, занимая память, а в действительности нужна лишь одна из них). И наконец, на мой взгляд, лучшая идея состоит в том, чтобы позволить исполняемому файлу решить, какую DLL загрузить при запуске. Например, если программа определила, что система не поддерживает акселерацию OpenGL, то лучше загрузить DLL с кодом DirectX, иначе загрузить OpenGL. Поэтому позднее связывание экономит память и уменьшает зависимость между DLL и исполняемым файлом. Однако в этом случае накладывается ограничение на экспортируемые объекты - экспортироваться могут лишь C-style функции. Классы и переменные не могут быть загружены, если программа использует позднее связывание. Давайте посмотрим, как обойти это ограничение с помощью интерфейсов.
DLL, спроектированная для позднего связывания обычно использует .def файл для определения тех объектов, которые она хочет экспортировать. Если вы не хотите использовать .def файл, можно просто использовать префикс __declspec(dllexport) перед экспортируемыми функциями. Оба метода делают одно и то же. Клиент загружает DLL, передавая имя файла DLL в функцию Win32 LoadLibrary().Эта функция возвращает хэндл HINSTANCE, который используется для работы с DLL и который необходим для выгрузки DLL из памяти, когда она становится не нужна. После загрузки DLL клиент может получить указатель на любую функцию при помощи функции GetProcAddress(), используя в качестве параметра имя требуемой функции.
//============================================================
// .def файл
LIBRARY myfirstdll.dll
DESCRIPTION 'My first DLL'
EXPORTS
MyFunction
//============================================================
/*
Реализация функции в DLL
*/
bool MyFunction(int parms)
{
//делаем что-нибудь
............
}
//============================================================
//Код клиента
/*
Объявление функции в действительности необходимо только для того,
чтобы опредедлить параметры. Объявления функций обычно содержаться в
заголовочном файле, поставляемом вместе с DLL.
Ключевое слово extern C в объявлении функции сообщает компилятору,
что нужно использовать соглашения об именовании переменных языка C.
*/
extern "C" bool MyFunction(int parms);
typedef bool (*MYFUNCTION)(int parms);
MYFUNCTION pfnMyFunc=0; //указатель на MyFunction
HINSTANCE hMyDll = ::LoadLibrary("myfirstdll.dll");
if(hMyDll != NULL)
{
//Определяем адрес функции
pfnMyFunc= (MYFUNCTION)::GetProcAddress(hMyDll, "MyFunction");
//Если неудачно - выгружаем DLL
if(pfnMyFunc== 0)
{
::FreeLibrary(hMyDll);
return;
}
//Вызываем функцию
bool result = pfnMyFunc(parms);
//Выгружаем DLL, если она больше нам не нужна
::FreeLibrary(hMyDll);
}
Как вы видите, код довольно прямолинеен. А теперь давайте посмотрим, как может быть реализована работа с "классами". Как было указано ранее, если используется позднее связывание, нет прямого способа импортировать из DLL классы, так что нам нужно реализовать "функциональность" класса с помощью интерфейса, содержащего все открытые (public) функции, исключая конструктор и деструктор. Интерфейс будет обычной C/C++ структурой, содержащей только виртуальные абстрактные функции-члены. Фактический класс в DLL будет наследоваться от этой структуры и будет реализовывать все функции, определенные в интерфейсе. Теперь, чтобы получить доступ к этому классу из приложения - клиента, все, что нужно сделать - это экспортировать C-style функции, соответствующие экземпляру класса и связать их с определенным нами интерфейсом для того, чтобы клиент мог их использовать. Для реализации такого метода нужна еще две функции, одна из которых создаст интерфейс, а вторая удалит интерфейс после того, как с ним закончили работать. Пример реализации этой идеи приведен ниже.
//============================================================
// .def файл
LIBRARY myinterface.dll
DESCRIPTION 'реализует интерфейс I_MyInterface
EXPORTS
GetMyInterface
FreeMyInterface
//============================================================
// Заголовочный фал, используемый в Dll и клиенте,
// который объявляет инетрфейс
// I_MyInterface.h
struct I_MyInterface
{
virtual bool Init(int parms)=0;
virtual bool Release()=0;
virtual void DoStuff() =0;
};
/*
Объявления экспортируемых функций Dll и определения типов указателей
на функции для простой загрузки и работы с функциями. Обратите
внимание на префикс extern "C", который сообщает компилятору о том,
что используются С-style функции
*/
extern "C"
{
HRESULT GetMyInterface(I_MyInterface ** pInterface);
typedef HRESULT (*GETINTERFACE)(I_MyInterface ** pInterface);
HRESULT FreeMyInterface(I_MyInterface ** pInterface);
typedef HRESULT (*FREEINTERFACE)(I_MyInterface ** pInterface);
}
//============================================================
//Реализация интерфейса в Dll
// MyInterface.h
class CMyClass: public I_MyInterface
{
public:
bool Init(int parms);
bool Release();
void DoStuff();
CMyClass();
~CMyClass();
//любые другие члены класса
............
private:
//любые члены класса
............
};
//============================================================
// Экспортируемые функции, которые создают и уничтожают интерфейс
// Dllmain.h
HRESULT GetMyInterface(I_MyInterface ** pInterface)
{
if(!*pInterface)
{
*pInterface= new CMyClass;
return S_OK;
}
return E_FAIL;
}
HRESULT FreeMyInterface(I_MyInterface ** pInterface)
{
if(!*pInterface)
return E_FAIL;
delete *pInterface;
*pInterface= 0;
return S_OK;
}
//============================================================
// Код клиента
//Объявления интерфейса и вызов функций
GETINTERFACE pfnInterface=0;//указатель на функцию GetMyInterface
I_MyInterface * pInterface =0;//указатель на структуру MyInterface
HINSTANCE hMyDll = ::LoadLibrary("myinterface.dll");
if(hMyDll != NULL)
{
//Определяем адрес функции
pfnInterface= (GETINTERFACE)::GetProcAddress(hMyDll,
"GetMyInterface");
//Выгружаем DLL, если предыдущая операция окончилась неудачей
if(pfnInterface == 0)
{
::FreeLibrary(hMyDll);
return;
}
//Вызываем функцию
HRESULT hr = pfnInterface(&pInterface);
//Выгружаем, если неудачно
if(FAILED(hr))
{
::FreeLibrary(hMyDll);
return;
}
//Интерфейс загружен, можно вызывать функции
pInterface->Init(1);
pInterface->DoStuff();
pInterface->Release();
//Освобождаем интерфейс
FREEINTERFACE pfnFree =
(FREEINTERFACE )::GetProcAddress(hMyDll,"FreeMyInterface");
if(pfnFree != 0)
pfnFree(&hMyDll);
//Выгружаем DLL
::FreeLibrary(hMyDll);
}
Этой информации вполне достаточно, чтобы вы почувствовали все удобство использования интерфейсов. Удачного программирования!