При импорте функций из DLL с помощью LoadLibrary() и GetProcAddr() имена функций в заголовочном файле значения не имеют, важны прежде всего их типы. При вызове GetProcAddr() ты всё равно получаешь "безымянный" указатель на импортируемую функцию, потом приводишь его к нужному типу функции и обращаешься к нему уже как к функции.А как вызвать из новой библиотеки функцию старой библиотеки? Имена ведь будут совпадать.
Подмена DLL-библиотеки
Модераторы: Hawk, Romeo, Absurd, DeeJayC, WinMain
Нужно сделать библиотеку-враппер, практически полностью повторяющую по функциональности оригинал, типа:
void Function1() {
Function1();
};
void Function2(TYPE v) {
Function2(v);
};
...
TYPE Function84(TYPE v) {
...
if (...) Function84(v);
...
};
...
Наверное, проще сделать через LoadLibrary?
void Function1() {
Function1();
};
void Function2(TYPE v) {
Function2(v);
};
...
TYPE Function84(TYPE v) {
...
if (...) Function84(v);
...
};
...
Наверное, проще сделать через LoadLibrary?
Недавно мне пришлось делать подобный модуль-обёртку для библиотеки Wing32.dll
В ней всего десяток функций, но по этому принципу ты сможешь написать их для своего модуля столько, сколько нужно. Для диагностики ошибок использован макрос ATLASSERT() из ATL, можешь использовать макрос ASSERT() из MFC или другое что-нибудь.
В ней всего десяток функций, но по этому принципу ты сможешь написать их для своего модуля столько, сколько нужно. Для диагностики ошибок использован макрос 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
Спасибо. Буду пробовать.
P.S. Задача - расширение функциональности библиотеки растеризации glide3x.dll без изменения вызывающих приложений.
P.S. Задача - расширение функциональности библиотеки растеризации glide3x.dll без изменения вызывающих приложений.
Если воспользуешься моим примером, то дальше всё будет довольно просто. В проекте модуля своей DLL используешь этот класс-обёртку как глобальный объект. Тогда при загрузке модуля он будет сам создаваться, а при выгрузке - уничтожаться. А те функции, которые будет экспортировать твоя DLL будут просто вызывать соответствующие методы этого класса.
А есть какой-то способ сделать инициализацию без классов?
Можно кончно, обычными функциями в стиле языка Си. Этот способ описан в MSDN, но это будет более трудоёмкий способ, если функций достаточно много.
Тогда сделаю типа такого:
void grGlideInit() {
*Fun1=LoadLibrary("Fun1");
...
(*GlideInit)();
}
...
void grGlideInit() {
*Fun1=LoadLibrary("Fun1");
...
(*GlideInit)();
}
...