Сейчас на форуме: hgdagon, asfa, bartolomeo (+4 невидимых)

 eXeL@B —› Программирование —› Передача фун-и в кач-ве параметра в С++
Посл.ответ Сообщение

Ранг: 39.6 (посетитель)
Активность: 0.020
Статус: Участник

Создано: 02 апреля 2007 14:41 · Поправил: NetSpider
· Личное сообщение · #1

Есть класс на С++.

#ifndef __PE_LIB_H
#define __PE_LIB_H

#include <windows.h>

typedef struct _GET_SECTION{
PIMAGE_SECTION_HEADER lpSection;
union{
DWORD dwTmp;
DWORD lParam;
};
DWORD FileAlignment;
DWORD SectionAlignment;
DWORD dwType;
}GET_SECTION, *PGET_SECTION;

//Types for GetSection function
enum {SEC_FIRSTPHISICAL, SEC_LASTPHISICAL, SEC_FIRSTVIRTUAL, SEC_LASTVIRTUAL, SEC_BYRO_FIRST,
SEC_BYRO_LAST, SEC_BYVA_FIRST, SEC_BYVA_LAST, SEC_FIRST, SEC_LAST, SEC_BYNUM};

typedef DWORD (WINAPI *lpProc) (void *, PIMAGE_SECTION_HEADER, DWORD);

class PELIB
{
protected:
//

public:
DWORD WINAPI AlignUp(DWORD dwValue,DWORD dwAlignment);
DWORD WINAPI AlignDown(DWORD dwValue,DWORD dwAlignment);
void WINAPI EnumSections(void *lpImage,lpProc lpEnumProc,DWORD lParam);
BOOL WINAPI IfInRange(DWORD dwOffset,DWORD dwStart,DWORD dwSize);
PIMAGE_SECTION_HEADER WINAPI GetSection(void *lpImage, DWORD lParam, DWORD dwType);

protected:
DWORD WINAPI FindSection(void *lpImage, PIMAGE_SECTION_HEADER lpSection, DWORD lParam);
};

#endif //PE_LIB_H

-----------------------------------------------------------cpp-------- ------------------------------------------------------------------
#include <windows.h>
#include "pe_lib.h"

DWORD WINAPI PELIB::AlignUp(DWORD dwValue,DWORD dwAlignment)
{
return dwValue&(~(dwAlignment+dwValue-1));
}

DWORD WINAPI PELIB::AlignDown(DWORD dwValue,DWORD dwAlignment)
{
return dwValue&(~(dwAlignment-1));
}

void WINAPI PELIB::EnumSections(void *lpImage,lpProc lpEnumProc,DWORD lParam)
{
DWORD SectNumber;
PIMAGE_SECTION_HEADER pSectHeader;
PIMAGE_NT_HEADERS pNtPeHeader;

pNtPeHeader = (PIMAGE_NT_HEADERS) (DWORD(lpImage) + PIMAGE_DOS_HEADER(lpImage)->e_lfanew);
SectNumber = pNtPeHeader->FileHeader.NumberOfSections;
pSectHeader = (PIMAGE_SECTION_HEADER)(pNtPeHeader+1);
do{
if (!lpEnumProc(lpImage, pSectHeader, lParam)) return;
pSectHeader++;
}while(SectNumber--);
return;
}

BOOL WINAPI PELIB::IfInRange(DWORD dwOffset,DWORD dwStart,DWORD dwSize)
{
if ((dwOffset>=dwStart)&&(dwOffset<(dwStart+dwSize))) return TRUE;
return FALSE;
}

DWORD WINAPI PELIB::FindSection(void *lpImage, PIMAGE_SECTION_HEADER lpSection, DWORD lParam)
{
PGET_SECTION GetSect = PGET_SECTION(lParam);
switch(GetSect->dwType){
case SEC_FIRSTPHISICAL:
if (lpSection->PointerToRawData>GetSect->dwTmp) return 0;
GetSect->dwTmp = lpSection->PointerToRawData;
GetSect->lpSection = lpSection;
break;
case SEC_LASTPHISICAL:
if (lpSection->PointerToRawData<GetSect->dwTmp) return 0;
GetSect->dwTmp = lpSection->PointerToRawData;
GetSect->lpSection = lpSection;
break;
case SEC_FIRSTVIRTUAL:
if (lpSection->VirtualAddress>GetSect->dwTmp) return 0;
GetSect->dwTmp = lpSection->VirtualAddress;
GetSect->lpSection = lpSection;
break;
case SEC_LASTVIRTUAL:
if (lpSection->VirtualAddress<GetSect->dwTmp) return 0;
GetSect->dwTmp = lpSection->VirtualAddress;
GetSect->lpSection = lpSection;
break;
case SEC_BYVA_FIRST:
if (IfInRange(GetSect->lParam,
AlignDown(lpSection->VirtualAddress, GetSect->SectionAlignment),
AlignUp(lpSection->Misc.VirtualSize, GetSect->SectionAlignment))) return 0;
GetSect->lpSection = lpSection;
return -1;
case SEC_BYVA_LAST:
if (IfInRange(GetSect->lParam,
AlignDown(lpSection->VirtualAddress, GetSect->SectionAlignment),
AlignUp(lpSection->Misc.VirtualSize, GetSect->SectionAlignment))) return 0;
GetSect->lpSection = lpSection;
break;
case SEC_BYRO_FIRST:
if (IfInRange(GetSect->lParam,
AlignDown(lpSection->PointerToRawData, GetSect->FileAlignment),
AlignUp(lpSection->SizeOfRawData, GetSect->FileAlignment))) return 0;
GetSect->lpSection = lpSection;
return -1;
case SEC_BYRO_LAST:
if (IfInRange(GetSect->lParam,
AlignDown(lpSection->PointerToRawData, GetSect->FileAlignment),
AlignUp(lpSection->SizeOfRawData, GetSect->FileAlignment))) return 0;
GetSect->lpSection = lpSection;
break;
default: return -1;
}
return 0;
}

PIMAGE_SECTION_HEADER WINAPI PELIB::GetSection(void *lpImage, DWORD lParam, DWORD dwType)
{
GET_SECTION GetSect;
PIMAGE_NT_HEADERS pNtPeHeader;

pNtPeHeader = (PIMAGE_NT_HEADERS) (DWORD(lpImage) + PIMAGE_DOS_HEADER(lpImage)->e_lfanew);
GetSect.FileAlignment = pNtPeHeader->OptionalHeader.FileAlignment;
if (GetSect.FileAlignment>0x200) GetSect.FileAlignment = 0x200;
GetSect.SectionAlignment = pNtPeHeader->OptionalHeader.SectionAlignment;
GetSect.dwType = dwType;
switch(dwType){
case SEC_FIRSTPHISICAL:case SEC_FIRSTVIRTUAL: GetSect.dwTmp = -1; break;
case SEC_LASTPHISICAL:case SEC_LASTVIRTUAL: GetSect.dwTmp = 0; break;
case SEC_BYVA_FIRST:case SEC_BYVA_LAST: case SEC_BYRO_FIRST: case SEC_BYRO_LAST: GetSect.lParam = lParam; break;
case SEC_FIRST: return (PIMAGE_SECTION_HEADER)(pNtPeHeader+1);
case SEC_LAST: return (PIMAGE_SECTION_HEADER)(pNtPeHeader+1) + pNtPeHeader->FileHeader.NumberOfSections - 1;
case SEC_BYNUM: return (PIMAGE_SECTION_HEADER)(pNtPeHeader+1) + lParam -1;
default: break;
}
GetSect.lpSection = 0;
EnumSections(lpImage, (lpProc) &FindSection, DWORD(&GetSect));
if (GetSect.lpSection) return GetSect.lpSection;
return 0;
}



Ранг: 39.6 (посетитель)
Активность: 0.020
Статус: Участник

Создано: 02 апреля 2007 14:42 · Поправил: NetSpider
· Личное сообщение · #2

При компиляции С++ ругается на знак & перед FindSection в строчке EnumSections(lpImage, (lpProc) &FindSection, DWORD(&GetSect));

Где ошибка или в чем? Я ведь передаю в фун-ю указатель на фун-ю FindSection.



Ранг: 122.2 (ветеран)
Активность: 0.040
Статус: Участник

Создано: 02 апреля 2007 14:47
· Личное сообщение · #3

Указатель на функцию будет FindSection, а не &FindSection



Ранг: 39.6 (посетитель)
Активность: 0.020
Статус: Участник

Создано: 02 апреля 2007 14:50 · Поправил: NetSpider
· Личное сообщение · #4

Тоже пробовал. Начинает ругаться на несоответствие типов.
Типа cannot covert from int ' ' to описалово функции lpProc

Сейчас VC++ на работе поставлю и подробно напишу коды ошибок.



Ранг: 39.6 (посетитель)
Активность: 0.020
Статус: Участник

Создано: 02 апреля 2007 15:01
· Личное сообщение · #5

В общем выдает такую ошибку если фун-я EnumSections(lpImage, (lpProc) &FindSection, DWORD(&GetSect));
D:\Work\C++\PE_CLASS\pe_lib\pe_lib.cpp(109) : error C2276: '&' : illegal operation on bound member function expression
Error executing cl.exe.

Если EnumSections(lpImage, (lpProc) FindSection, DWORD(&GetSect));
:\Work\C++\PE_CLASS\pe_lib\pe_lib.cpp(109) : error C2440: 'type cast' : cannot convert from '' to 'unsigned long (__stdcall *)(void *,struct _IMAGE_SECTION_HEADER *,unsigned long)'
None of the functions with this name in scope match the target type
Error executing cl.exe.



Ранг: 39.6 (посетитель)
Активность: 0.020
Статус: Участник

Создано: 02 апреля 2007 15:02 · Поправил: NetSpider
· Личное сообщение · #6

По идее правильно (lpProc) &FindSection
Но почему ошибка? Кто знает? У меня уже был опыт передачи параметров в кач-ве фун-ии и все нормально раньше получалось, а теперь компилятор ругается.



Ранг: 122.2 (ветеран)
Активность: 0.040
Статус: Участник

Создано: 02 апреля 2007 15:05
· Личное сообщение · #7

Посмотрел повнимательней. У тебя функция FindSection является методом класса. Поэтому типы и не соответствуют. Или объяви ее как глобальную или попробуй объявить статической. Просто для методов класса неявно присутствует еще один параметр (this, указатель на объект, с которым метод будет работать). Поэтому сигнатуры функций и не совпадают




Ранг: 66.1 (постоянный)
Активность: 0.040
Статус: Участник

Создано: 02 апреля 2007 15:05
· Личное сообщение · #8

Попробуй (void *)FindSection



Ранг: 39.6 (посетитель)
Активность: 0.020
Статус: Участник

Создано: 02 апреля 2007 15:08 · Поправил: NetSpider
· Личное сообщение · #9

AdOLF_04
Попробовал (void *) получил снова D:\Work\C++\PE_CLASS\pe_lib\pe_lib.cpp(109) : error C2276: '&' : illegal operation on bound member function expression

egorovshura
Спасибо. Сейчас по-другому попробую.



Ранг: 39.6 (посетитель)
Активность: 0.020
Статус: Участник

Создано: 02 апреля 2007 15:56 · Поправил: NetSpider
· Личное сообщение · #10

Что-то млин я соВсем запарился. Пробовал FindSection в public помещать толку никакого. Необходимо, что бы FindSection оставался членом класса. Как передать FindSection в кач-ве параметра фун-ии?



Ранг: 122.2 (ветеран)
Активность: 0.040
Статус: Участник

Создано: 02 апреля 2007 16:14
· Личное сообщение · #11

NetSpider пишет:
Что-то млин я соВсем запарился. Пробовал FindSection в public помещать толку никакого. Необходимо, что бы FindSection оставался членом класса. Как передать FindSection в кач-ве параметра фун-ии?

Если будет оставаться членом класса, то не сможешь передать. Я же говорю неявно указатель на объект передается, а вызывающая фукция не знает какой указатель передавать. Делай либо глобальную функцию либо статическую



Ранг: 39.6 (посетитель)
Активность: 0.020
Статус: Участник

Создано: 02 апреля 2007 16:30
· Личное сообщение · #12

Жаль. Сделаю фун-ю статической. Оказывается над такой проблемой размышляли по адресу
_http://nornad.blogspot.com/2006/11/blog-post_08.html

Буду думать...



Ранг: 17.6 (новичок)
Активность: 0.01=0.01
Статус: Участник

Создано: 02 апреля 2007 20:00
· Личное сообщение · #13

Адрес функции передавай как константу integer
В вызываемом теле преобразуешь



Ранг: 163.7 (ветеран)
Активность: 0.070
Статус: Участник

Создано: 03 апреля 2007 01:36
· Личное сообщение · #14

typedef DWORD (PELIB:: *lpProc) (void *, PIMAGE_SECTION_HEADER, DWORD);



Ранг: 39.6 (посетитель)
Активность: 0.020
Статус: Участник

Создано: 03 апреля 2007 11:26
· Личное сообщение · #15

vitokop
Попробовал. Ругается на невозможность преобразования типов.

S_T_A_S_
Тоже пробовал. Получил
:\Work\C++\PE_CLASS\pe_lib\pe_lib.h(57) : error C2653: 'PELIB' : is not a class or namespace name
D:\Work\C++\PE_CLASS\pe_lib\pe_lib.h(57) : error C2645: no qualified name for pointer to member (found ':: *')



Ранг: 20.8 (новичок)
Активность: 0.010
Статус: Участник

Создано: 04 апреля 2007 12:46
· Личное сообщение · #16

А объявлял тип указателя до, или после объявления класса, надо либо после объявления класса, либо сделать forward declaration (не знаю как по русски правильно перевести):
class PELIB;
typedef ...



Ранг: 39.6 (посетитель)
Активность: 0.020
Статус: Участник

Создано: 04 апреля 2007 19:46 · Поправил: NetSpider
· Личное сообщение · #17

Player
Сделал предварительное объявление класса и после него
typedef DWORD (PELIB:: *lpProc) (void *lpImage, PIMAGE_SECTION_HEADER lpSection, DWORD lParam);

Вроде прокатило. Но теперь ругается в другом месте.
D:\Work\C++\PE_CLASS\pe_lib\pe_lib.cpp(24) : error C2064: term does not evaluate to a function
Error executing cl.exe.

void WINAPI PELIB::EnumSections(void *lpImage,lpProc lpEnumProc,DWORD lParam)
{
DWORD SectNumber;
PIMAGE_SECTION_HEADER pSectHeader;
PIMAGE_NT_HEADERS pNtPeHeader;

pNtPeHeader = (PIMAGE_NT_HEADERS) (DWORD(lpImage) + PIMAGE_DOS_HEADER(lpImage)->e_lfanew);
SectNumber = pNtPeHeader->FileHeader.NumberOfSections;
pSectHeader = (PIMAGE_SECTION_HEADER)(pNtPeHeader+1);
do{
if (!(lpEnumProc(lpImage, pSectHeader, lParam))) return; /// в этой строке ошибка
pSectHeader++;
}while(SectNumber--);
return;
}



Ранг: 39.6 (посетитель)
Активность: 0.020
Статус: Участник

Создано: 04 апреля 2007 20:26
· Личное сообщение · #18

Урраа.. Кажись получилось
Сделал так if (!((this->*lpEnumProc)(lpImage, pSectHeader, lParam))) return;

Компилятор сказал, что все путем.



Ранг: 39.6 (посетитель)
Активность: 0.020
Статус: Участник

Создано: 04 апреля 2007 20:37 · Поправил: NetSpider
· Личное сообщение · #19

Проверил в отладчике. Все работает. Огромное спасибо за оказанную помощь.

Тему считаю закрытой.


 eXeL@B —› Программирование —› Передача фун-и в кач-ве параметра в С++
Эта тема закрыта. Ответы больше не принимаются.
   Для печати Для печати