Тип функции, принимающей в качестве параметра шаблон
От: SchweinDeBurg Россия http://zarezky.spb.ru/
Дата: 28.06.05 08:36
Оценка:
Доброго времени суток нам всем!

Вопрос навеян желанием усовершенствовать [Win32] Выполнение кода в чужом процессе
Автор: SchweinDeBurg
Дата: 27.06.05


Пусть имеется объявление

template <class _Data_t>
struct THREAD_PARAM
{
    FARPROC pfnGetModuleHandle;
    FARPROC pfnGetProcAddress;
    _Data_t data;
};

(_Data_t по смыслу может быть произвольной структурой с "простыми" полями.)

Могу ли я (и если да — то как) теперь ввести через typedef тип функции (не шаблонной), которая в качестве параметра принимает указатель на "произвольный" (то есть "конкретизированный" любым типом) экземпляр THREAD_PARAM<>?

P.S.
Желательная минимальная версия компилятора — VC++ 7.0
[ posted via RSDN@Home 1.1.4 beta 7 r501, accompanied by silence ]
- Искренне ваш, Поросенок Пафнутий ~ ICQ#116846877
In Windows, there’s always a catch… © Paul DiLascia
Re: Тип функции, принимающей в качестве параметра шаблон
От: execve  
Дата: 28.06.05 08:44
Оценка: +1
Здравствуйте, SchweinDeBurg, Вы писали:

SDB>Могу ли я (и если да — то как) теперь ввести через typedef тип функции (не шаблонной), которая в качестве параметра принимает указатель на "произвольный" (то есть "конкретизированный" любым типом) экземпляр THREAD_PARAM<>?


Вариант 1:
typedef void (*MyFunc)(void*);


Вариант 2:
struct THREAD_PARAM_PARENT
{
    FARPROC pfnGetModuleHandle;
    FARPROC pfnGetProcAddress;
};

template <class _Data_t>
struct THREAD_PARAM:
    public THREAD_PARAM_PARENT
{
    _Data_t data;
};

typedef void (*MyFunc)(THREAD_PARAM_PARENT*);


На самом деле не очень понятно, что ты будешь делать с этим указателем.
Ты же даже не будешь знать размер переданной в качестве параметра структуры THREAD_PARAM<>.
Re[2]: Тип функции, принимающей в качестве параметра шаблон
От: SchweinDeBurg Россия http://zarezky.spb.ru/
Дата: 28.06.05 08:52
Оценка:
Здравствуйте, execve, Вы писали:

E>Вариант 1:

E>Вариант 2:

Это все понятно, но это — "в обход".

E>На самом деле не очень понятно, что ты будешь делать с этим указателем.


Хорошо, "предположим, что задача решена". Мне хочется, чтобы "пользователь" шаблона мог действовать примерно так:

struct MY_DATA
{
...
};

DWORD __stdcall MyProc(THREAD_PARAM<MY_DATA>* pParam)
{
...
}

При этом в "библиотечном" коде используется некий "обобщенный" тип, которому соответствует и MyProc(), и DWORD __stdcall MyProc(THREAD_PARAM<YOUR_DATA>* pParam), etc.
[ posted via RSDN@Home 1.1.4 beta 7 r501, accompanied by silence ]
- Искренне ваш, Поросенок Пафнутий ~ ICQ#116846877
In Windows, there’s always a catch… © Paul DiLascia
Re[3]: Тип функции, принимающей в качестве параметра шаблон
От: execve  
Дата: 28.06.05 09:06
Оценка:
Здравствуйте, SchweinDeBurg, Вы писали:

SDB>Хорошо, "предположим, что задача решена". Мне хочется, чтобы "пользователь" шаблона мог действовать примерно так:


SDB>
SDB>struct MY_DATA
SDB>{
SDB>...
SDB>};

SDB>DWORD __stdcall MyProc(THREAD_PARAM<MY_DATA>* pParam)
SDB>{
SDB>...
SDB>}
SDB>

SDB>При этом в "библиотечном" коде используется некий "обобщенный" тип, которому соответствует и MyProc(), и DWORD __stdcall MyProc(THREAD_PARAM<YOUR_DATA>* pParam), etc.

Уж не хочешь ли ты экспортировать шаблон MyFunc?
Re[4]: Тип функции, принимающей в качестве параметра шаблон
От: SchweinDeBurg Россия http://zarezky.spb.ru/
Дата: 28.06.05 09:09
Оценка:
Здравствуйте, execve, Вы писали:

E>Уж не хочешь ли ты экспортировать шаблон MyFunc?


И в мыслях не было! Я уже слишком стар для подобных хотений...
[ posted via RSDN@Home 1.1.4 beta 7 r501, accompanied by silence ]
- Искренне ваш, Поросенок Пафнутий ~ ICQ#116846877
In Windows, there’s always a catch… © Paul DiLascia
Re[3]: Тип функции, принимающей в качестве параметра шаблон
От: MaximE Великобритания  
Дата: 28.06.05 09:10
Оценка: 12 (1)
SchweinDeBurg wrote:

> Здравствуйте, execve, Вы писали:

>
> E>Вариант 1:
> E>Вариант 2:
>
> Это все понятно, но это — "в обход".
>
> E>На самом деле не очень понятно, что ты будешь делать с этим указателем.
>
> Хорошо, "предположим, что задача решена". Мне хочется, чтобы "пользователь" шаблона мог действовать примерно так:
>
>
> struct MY_DATA
> {
> ...
> };
>
> DWORD __stdcall MyProc(THREAD_PARAM<MY_DATA>* pParam)
> {
> ...
> }
>

> При этом в "библиотечном" коде используется некий "обобщенный" тип, которому соответствует и MyProc(), и DWORD __stdcall MyProc(THREAD_PARAM<YOUR_DATA>* pParam), etc.

Задача типовая. Используй boost::thread:

void my_thread_fun(int a, int b, int c);
// ...
boost::thread(boost::bind(my_thread_fun, 1, 2, 3));


Или boost::function без thread:
typedef boost::function<void()> thread_fun;

DWORD WINAPI thread_thunk(void* arg)
{
     std::auto_ptr<thread_fun> f(static_cast<thread_fun*>(arg));
     (*f)();
     return 0;
}

void create_thread(thread_fun const& f)
{
     std::auto_ptr<thread_fun> arg(new thread_fun(f));
     CreateThread(..., thread_thunk, arg.get(), ...);
     arg.release();
}

void my_thread_fun(int a, int b, int c);
// ...
create_thread(boost::bind(my_thread_fun, 1, 2, 3));


--
Maxim Yegorushkin
Posted via RSDN NNTP Server 1.9
Re[4]: Тип функции, принимающей в качестве параметра шаблон
От: SchweinDeBurg Россия http://zarezky.spb.ru/
Дата: 28.06.05 09:25
Оценка:
Здравствуйте, MaximE, Вы писали:

ME>Задача типовая. Используй boost::thread:


М-м-м... если таки овлечься от потоков... Правильно ли я понимаю, что в C++ нет "прямой" синтаксической конструкции а-ля

typedef void (* PFN)(PARAM_конкретизированный_все_равно_чем* pParam);

которая бы "сказала" компилятору, что PFN — это указатель на функцию, принимающую адрес чем-то конкретизированного PARAM<>?
[ posted via RSDN@Home 1.1.4 beta 7 r501, accompanied by silence ]
- Искренне ваш, Поросенок Пафнутий ~ ICQ#116846877
In Windows, there’s always a catch… © Paul DiLascia
Re[5]: Тип функции, принимающей в качестве параметра шаблон
От: MaximE Великобритания  
Дата: 28.06.05 09:31
Оценка:
SchweinDeBurg wrote:

> Здравствуйте, MaximE, Вы писали:

>
> ME>Задача типовая. Используй boost::thread:
>
> М-м-м... если таки овлечься от потоков... Правильно ли я понимаю, что в C++ нет "прямой" синтаксической конструкции а-ля
>
>
> typedef void (* PFN)(PARAM_конкретизированный_все_равно_чем* pParam);
>

> которая бы "сказала" компилятору, что PFN — это указатель на функцию, принимающую адрес чем-то конкретизированного PARAM<>?

Шаблон ф-ции это еще не ф-ция, а лишь что-то, из чего может быть сгенерирована ф-ция. Адрес шаблона ф-ции взять нельзя.

--
Maxim Yegorushkin
Posted via RSDN NNTP Server 1.9
Re[6]: Тип функции, принимающей в качестве параметра шаблон
От: SchweinDeBurg Россия http://zarezky.spb.ru/
Дата: 28.06.05 09:45
Оценка:
Здравствуйте, MaximE, Вы писали:

ME>Шаблон ф-ции это еще не ф-ция, а лишь что-то, из чего может быть сгенерирована ф-ция. Адрес шаблона ф-ции взять нельзя.


Безусловно. Но! — вот эти две функции шаблонными не являются, насколько я понимаю:

template <class _Data_t>
struct PARAM
{
    int x;
    char c;
    _Data_t data;
};

struct MY_DATA { ... };
struct YOUR_DATA { ... };

void MyProc(PARAM<MY_DATA>* pParam) { ... }
void YourProc(PARAM<YOUR_DATA>* pParam) { ... }

И получается, что обобщенного типа, которому они обе "соответствуют", не существует?
[ posted via RSDN@Home 1.1.4 beta 7 r501, accompanied by silence ]
- Искренне ваш, Поросенок Пафнутий ~ ICQ#116846877
In Windows, there’s always a catch… © Paul DiLascia
Re[7]: Тип функции, принимающей в качестве параметра шаблон
От: CrystaX Россия https://crystax.me/
Дата: 28.06.05 09:56
Оценка: 24 (1)
Здравствуйте, SchweinDeBurg, Вы писали:

SDB>Здравствуйте, MaximE, Вы писали:


ME>>Шаблон ф-ции это еще не ф-ция, а лишь что-то, из чего может быть сгенерирована ф-ция. Адрес шаблона ф-ции взять нельзя.


SDB>Безусловно. Но! — вот эти две функции шаблонными не являются, насколько я понимаю:


SDB>
SDB>template <class _Data_t>
SDB>struct PARAM
SDB>{
SDB>    int x;
SDB>    char c;
SDB>    _Data_t data;
SDB>};

SDB>struct MY_DATA { ... };
SDB>struct YOUR_DATA { ... };

SDB>void MyProc(PARAM<MY_DATA>* pParam) { ... }
SDB>void YourProc(PARAM<YOUR_DATA>* pParam) { ... }
SDB>

SDB>И получается, что обобщенного типа, которому они обе "соответствуют", не существует?

Как раз обобщенный тип есть:
template <typename Data>
struct param_helper
{
    typedef void (*type)(PARAM<Data> *);
};

// Использование

param_helper<MY_DATA>::type fun1 = &MyProc;
param_helper<YOUR_DATA>::type fun2 = &YourProc;


Но только типы у fun1 и fun2 будут разные.
... << RSDN@Home 1.1.4 beta 7 rev. 447>>
Re[8]: Тип функции, принимающей в качестве параметра шаблон
От: SchweinDeBurg Россия http://zarezky.spb.ru/
Дата: 28.06.05 10:25
Оценка:
Здравствуйте, CrystaX, Вы писали:

CX>Как раз обобщенный тип есть:

CX>Но только типы у fun1 и fun2 будут разные.

Уф-ф-ф... кажется понял.... то есть, если я напишу вот так:

template <class _Data_t>
struct THREAD_PARAM
{
    FARPROC pfnGetModuleHandle;
    FARPROC pfnGetProcAddress;
    _Data_t data;
};

// interface

template <class _Data_t, DWORD(__stdcall* _Proc)(THREAD_PARAM<_Data_t>*)>
class CRemoteProc
{
// construction/destruction
public:
    CRemoteProc(HANDLE hProcess, int cbMaxCode = 4096);
    ~CRemoteProc(void);

// copying/assignment - disabled and thus not implemented
private:
    CRemoteProc(const CRemoteProc& rhs);
    CRemoteProc& operator=(const CRemoteProc& rhs);

// type conversion
public:
    operator LPTHREAD_START_ROUTINE(void) const;

// attributes
private:
    HANDLE m_hProcess;
    void* m_codePtr;
};

// implementation

template <class _Data_t, DWORD(__stdcall* _Proc)(THREAD_PARAM<_Data_t>*)>
inline CRemoteProc<_Data_t, _Proc>::CRemoteProc(HANDLE hProcess, int cbMaxCode):
m_hProcess(hProcess),
m_codePtr(NULL)
{
    m_codePtr = ::VirtualAllocEx(hProcess, NULL, cbMaxCode, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
    ::WriteProcessMemory(m_hProcess, m_codePtr, _Proc, cbMaxCode, NULL);
}

template <class _Data_t, DWORD(__stdcall* _Proc)(THREAD_PARAM<_Data_t>*)>
inline CRemoteProc<_Data_t, _Proc>::~CRemoteProc(void)
{
    ::VirtualFreeEx(m_hProcess, m_codePtr, 0, MEM_RELEASE);
    m_codePtr = NULL;
}

template <class _Data_t, DWORD(__stdcall* _Proc)(THREAD_PARAM<_Data_t>*)>
inline CRemoteProc<_Data_t, _Proc>::operator LPTHREAD_START_ROUTINE(void) const
{
    return (reinterpret_cast<LPTHREAD_START_ROUTINE>(m_codePtr));
}

то в качестве _Proc компилятор пропустит только нечто вида

DWORD __stdcall MyProc(THREAD_PARAM<некий_тип>* pParam) { ... }

и ничего кроме. Правильно?
[ posted via RSDN@Home 1.1.4 beta 7 r501, accompanied by silence ]
- Искренне ваш, Поросенок Пафнутий ~ ICQ#116846877
In Windows, there’s always a catch… © Paul DiLascia
Re[9]: Тип функции, принимающей в качестве параметра шаблон
От: CrystaX Россия https://crystax.me/
Дата: 28.06.05 11:05
Оценка:
Здравствуйте, SchweinDeBurg, Вы писали:

SDB>то в качестве _Proc компилятор пропустит только нечто вида


SDB>
SDB>DWORD __stdcall MyProc(THREAD_PARAM<некий_тип>* pParam) { ... }
SDB>

SDB>и ничего кроме. Правильно?

Эээ... Ну да, так и будет.
... << RSDN@Home 1.1.4 beta 7 rev. 447>>
Re[10]: Тип функции, принимающей в качестве параметра шаблон
От: SchweinDeBurg Россия http://zarezky.spb.ru/
Дата: 28.06.05 11:09
Оценка: :)
Здравствуйте, CrystaX, Вы писали:

CX>Эээ... Ну да, так и будет.


М-дя... "надо чаще... встречаться..." Года три уже своих шаблонов не писал, забыл все на свете... Спасибо за "наводку" — именно кусок кода в Re[7]: Тип функции, принимающей в качестве параметра шаблон
Автор: CrystaX
Дата: 28.06.05
и наставил меня на путь истинный.
[ posted via RSDN@Home 1.1.4 beta 7 r501, accompanied by silence ]
- Искренне ваш, Поросенок Пафнутий ~ ICQ#116846877
In Windows, there’s always a catch… © Paul DiLascia
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.