Подмена DLL-библиотеки

Модераторы: Hawk, Romeo, Absurd, DeeJayC, WinMain

Аватара пользователя
WinMain
Сообщения: 929
Зарегистрирован: 14 янв 2005, 10:30
Откуда: Москва
Контактная информация:

А как вызвать из новой библиотеки функцию старой библиотеки? Имена ведь будут совпадать.
При импорте функций из DLL с помощью LoadLibrary() и GetProcAddr() имена функций в заголовочном файле значения не имеют, важны прежде всего их типы. При вызове GetProcAddr() ты всё равно получаешь "безымянный" указатель на импортируемую функцию, потом приводишь его к нужному типу функции и обращаешься к нему уже как к функции.
Defder
Сообщения: 64
Зарегистрирован: 24 май 2005, 12:25

Нужно сделать библиотеку-враппер, практически полностью повторяющую по функциональности оригинал, типа:

void Function1() {
Function1();
};

void Function2(TYPE v) {
Function2(v);
};

...

TYPE Function84(TYPE v) {
...
if (...) Function84(v);
...
};

...



Наверное, проще сделать через LoadLibrary?
Аватара пользователя
WinMain
Сообщения: 929
Зарегистрирован: 14 янв 2005, 10:30
Откуда: Москва
Контактная информация:

Недавно мне пришлось делать подобный модуль-обёртку для библиотеки Wing32.dll
В ней всего десяток функций, но по этому принципу ты сможешь написать их для своего модуля столько, сколько нужно. Для диагностики ошибок использован макрос ATLASSERT() из ATL, можешь использовать макрос ASSERT() из MFC или другое что-нибудь.

Код: Выделить всё

#if (!defined _WING32DLL_H_)
#define _WING32DLL_H_

template <typename T> class TFuncPtr
{
	T *func;
public:
	TFuncPtr(FARPROC pfn = NULL){
		SetAddr(pfn);
	}
	TFuncPtr(TFuncPtr<T> & fn)	{
		SetAddr(fn);
	}
	void SetAddr(FARPROC pfn)	{
		func = reinterpret_cast<T*>(pfn);
	}
	T& operator *() const	{
		return *func;		
	}
	BOOL operator !() const	{
		return func == NULL;
	}
	void operator =(FARPROC pfn){
		SetAddr(pfn);
	}
	operator FARPROC() const	{
		return func;
	}
};

class CLoadLibrary
{
public:
	CLoadLibrary() :
		m_hModule(NULL)
	{
	}
	CLoadLibrary(LPCTSTR lpFileName)
	{
		m_hModule = ::LoadLibrary(lpFileName);
	}
	~CLoadLibrary()
	{
		if (m_hModule != NULL)
			::FreeLibrary(m_hModule);
	}
	operator HMODULE() const
	{
		return m_hModule;
	}
	FARPROC GetProcAddress(LPCSTR lpProcName)
	{
		return (m_hModule != NULL)? 
			::GetProcAddress(m_hModule, lpProcName) : NULL;
	}
//protected:
	HMODULE m_hModule;
};

typedef enum WING_DITHER_TYPE
{
	WING_DISPERSED_4x4,
	WING_DISPERSED_8x8,
	WING_CLUSTERED_4x4
} WING_DITHER_TYPE;

class CWing32DLL : public CLoadLibrary
{
	TFuncPtr <HDC WINAPI (void)> pWinGCreateDC;
	TFuncPtr <BOOL WINAPI (BITMAPINFO FAR*)> pWinGRecommendDIBFormat;
	TFuncPtr <HBITMAP WINAPI (HDC, BITMAPINFO const FAR*, void FAR* FAR*)> pWinGCreateBitmap;
	TFuncPtr <void FAR *WINAPI (HBITMAP, BITMAPINFO FAR*)> pWinGGetDIBPointer;
	TFuncPtr <UINT WINAPI (HDC, UINT, UINT, RGBQUAD FAR*)> pWinGGetDIBColorTable;
	TFuncPtr <UINT WINAPI (HDC, UINT, UINT, RGBQUAD const FAR*)> pWinGSetDIBColorTable;
	TFuncPtr <HPALETTE WINAPI (void)> pWinGCreateHalftonePalette;
	TFuncPtr <HBRUSH WINAPI (HDC, COLORREF, WING_DITHER_TYPE)> pWinGCreateHalftoneBrush;
	TFuncPtr <BOOL WINAPI (HDC, int, int, int, int, HDC, int, int)> pWinGBitBlt;
	TFuncPtr <BOOL WINAPI (HDC, int, int, int, int, HDC, int, int, int, int)> pWinGStretchBlt;

public:
	CWing32DLL() : CLoadLibrary(_T("Wing32.dll"))
	{
		if (!m_hModule)
			OnLoadWing32DllError();
		else
		{
			pWinGCreateDC = GetProcAddress("WinGCreateDC");
			pWinGRecommendDIBFormat = GetProcAddress("WinGRecommendDIBFormat");
			pWinGCreateBitmap = GetProcAddress("WinGCreateBitmap");
			pWinGGetDIBPointer = GetProcAddress("WinGGetDIBPointer");
			pWinGGetDIBColorTable = GetProcAddress("WinGGetDIBColorTable");
			pWinGSetDIBColorTable = GetProcAddress("WinGSetDIBColorTable");
			pWinGCreateHalftonePalette = GetProcAddress("WinGCreateHalftonePalette");
			pWinGCreateHalftoneBrush = GetProcAddress("WinGCreateHalftoneBrush");
			pWinGBitBlt = GetProcAddress("WinGBitBlt");
			pWinGStretchBlt = GetProcAddress("WinGStretchBlt");
		}
	}
	HDC WINAPI WinGCreateDC( void )
	{
		ATLASSERT(!pWinGCreateDC == FALSE);
		return (*pWinGCreateDC)();
	}
	BOOL WINAPI WinGRecommendDIBFormat( BITMAPINFO FAR *pFormat )
	{
		ATLASSERT(!pWinGRecommendDIBFormat == FALSE);
		return (*pWinGRecommendDIBFormat)(pFormat);
	}
	HBITMAP WINAPI WinGCreateBitmap( HDC WinGDC, BITMAPINFO const FAR *pHeader, void FAR *FAR *ppBits )
	{
		ATLASSERT(!pWinGCreateBitmap == FALSE);
		return (*pWinGCreateBitmap)(WinGDC, pHeader, ppBits);
	}
	void FAR *WINAPI WinGGetDIBPointer( HBITMAP WinGBitmap, BITMAPINFO FAR *pHeader )
	{
		if (!pWinGGetDIBPointer == FALSE)
			(*pWinGGetDIBPointer)(WinGBitmap, pHeader);
	}
	UINT WINAPI WinGGetDIBColorTable( HDC WinGDC, UINT StartIndex, UINT NumberOfEntries, RGBQUAD FAR *pColors )
	{
		ATLASSERT(!pWinGGetDIBColorTable == FALSE);
		return (*pWinGGetDIBColorTable)(WinGDC, StartIndex, NumberOfEntries, pColors);
	}
	UINT WINAPI WinGSetDIBColorTable( HDC WinGDC, UINT StartIndex, UINT NumberOfEntries, RGBQUAD const FAR *pColors )
	{
		ATLASSERT(!pWinGSetDIBColorTable == FALSE);
		return (*pWinGSetDIBColorTable)(WinGDC, StartIndex, NumberOfEntries, pColors);
	}
	HPALETTE WINAPI WinGCreateHalftonePalette( void )
	{
		ATLASSERT(!pWinGCreateHalftonePalette == FALSE);
		return (*pWinGCreateHalftonePalette)();
	}
	HBRUSH WINAPI WinGCreateHalftoneBrush( HDC Context, COLORREF crColor, WING_DITHER_TYPE DitherType )
	{
		ATLASSERT(!pWinGCreateHalftoneBrush == FALSE);
		return (*pWinGCreateHalftoneBrush)(Context, crColor, DitherType);
	}
	BOOL WINAPI WinGBitBlt( HDC hdcDest, int nXDest, int nYDest, 
		 int nWidth, int nHeight, HDC hdcSrc, int nXSrc, int nYSrc )
	{
		ATLASSERT(!pWinGBitBlt == FALSE);
		return (*pWinGBitBlt)(hdcDest, nXDest, nYDest, nWidth, nHeight, hdcSrc, nXSrc, nYSrc);
	}
	BOOL WINAPI WinGStretchBlt( HDC hdcDest, int nXDest, int nYDest, int nWidth, int nHeight, 
		 HDC hdcSrc, int nXSrc, int nYSrc, int nWidthSrc, int nHeightSrc )
	{
		ATLASSERT(!pWinGStretchBlt == FALSE);
		return (*pWinGStretchBlt)(hdcDest, nXDest, nYDest, nWidth, nHeight,
								  hdcSrc, nXSrc, nYSrc, nWidthSrc, nHeightSrc);
	}
	//

protected:
	virtual void OnLoadWing32DllError()
	{
		ATLASSERT(m_hModule != NULL);
	}
};

#endif
Defder
Сообщения: 64
Зарегистрирован: 24 май 2005, 12:25

Спасибо. Буду пробовать.

P.S. Задача - расширение функциональности библиотеки растеризации glide3x.dll без изменения вызывающих приложений.
Аватара пользователя
WinMain
Сообщения: 929
Зарегистрирован: 14 янв 2005, 10:30
Откуда: Москва
Контактная информация:

Если воспользуешься моим примером, то дальше всё будет довольно просто. В проекте модуля своей DLL используешь этот класс-обёртку как глобальный объект. Тогда при загрузке модуля он будет сам создаваться, а при выгрузке - уничтожаться. А те функции, которые будет экспортировать твоя DLL будут просто вызывать соответствующие методы этого класса.
Defder
Сообщения: 64
Зарегистрирован: 24 май 2005, 12:25

А есть какой-то способ сделать инициализацию без классов?
Аватара пользователя
WinMain
Сообщения: 929
Зарегистрирован: 14 янв 2005, 10:30
Откуда: Москва
Контактная информация:

Можно кончно, обычными функциями в стиле языка Си. Этот способ описан в MSDN, но это будет более трудоёмкий способ, если функций достаточно много.
Defder
Сообщения: 64
Зарегистрирован: 24 май 2005, 12:25

Тогда сделаю типа такого:

void grGlideInit() {
*Fun1=LoadLibrary("Fun1");
...
(*GlideInit)();
}

...
Ответить