Модераторы: Partizan, gambit
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Указатель на делегат 
:(
    Опции темы
Red Wind
Дата 9.5.2007, 13:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 280
Регистрация: 25.6.2004
Где: Минск

Репутация: нет
Всего: 2



С праздником!
У меня есть определённый делегат. Нужно получить указатель на на этот делегат, что бы использовать в unmenaged коде. Вообще в framework 2.0 есть специальный метод Marshal.GetFunctionPointerForDelegate. Но мне нужно обойдтись возможностями первого фрэймворка. Скажите, как это мождно сделать?
PM MAIL ICQ   Вверх
marcusmae
Дата 9.5.2007, 14:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


stravaganza
**


Профиль
Группа: Участник
Сообщений: 874
Регистрация: 26.3.2006

Репутация: 22
Всего: 39



И Вас с праздником!

Using managed delegates from unmanaged code

Цитата

Basically, you have to create a singleton struct to hold your delegate:
Код

typedef bool (*fMyCallback)(unsigned long uUserData);

__delegate bool MyCallback(__int32 uUserData);

__gc struct MyCallbackWrapper {
    [MarshalAsAttribute(UnmanagedType::FunctionPtr)]
    MyCallback *m_call;
};

__nogc struct MyCallbackWrapperUnmanaged {
    fMyCallBack m_callUnmanged;
};

fMyCallBack MakeUnmanagedCallback(MyCallback call)
{
    __gc struct MyCallbackWrapper *wrapper = new MyCallbackWrapper();
    wrapper->m_call = call;
    MyCallbackWrapperUnmanaged wrapperUnmanaged;
    Marshal::StructureToPtr(wrapper, &wrapperUnmanaged, false);
    return wrapperUnmanaged.m_callUnmanaged;
}



Подойдёт?

Это сообщение отредактировал(а) marcusmae - 9.5.2007, 14:08


--------------------
ἀπὸ μηχανῆς θεός
PM MAIL ICQ GTalk   Вверх
Red Wind
Дата 9.5.2007, 15:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 280
Регистрация: 25.6.2004
Где: Минск

Репутация: нет
Всего: 2



Боюсь, что не пойдёт. С++ я не знаю, и разобраться с этим для меня проблема.
PM MAIL ICQ   Вверх
marcusmae
Дата 9.5.2007, 17:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


stravaganza
**


Профиль
Группа: Участник
Сообщений: 874
Регистрация: 26.3.2006

Репутация: 22
Всего: 39



Цитата(Red Wind @  9.5.2007,  15:31 Найти цитируемый пост)
С++ я не знаю, и разобраться с этим для меня проблема.


Наверно, так или иначе Вам придётся написать managed/unmanaged мост. Из всего семейства языков .NET сочетать managed и unmanaged можно только в плюсах...

Вдруг помогут мои комментарии к коду?

Код

// объявили тип указателя на функцию (действует как алиас)
typedef bool (*fMyCallback)(unsigned long uUserData);

// это, собственно, делегат; всё так же как на C#. Напишите свой.
__delegate bool MyCallback(__int32 uUserData);

// __gc (Garbage Collector) в старом синтаксисе (в .NET1.1) указывает на то, это - managed-структура
__gc struct MyCallbackWrapper {
    [MarshalAsAttribute(UnmanagedType::FunctionPtr)]
    // здесь держим экземпляр делегата
    MyCallback *m_call;
};

// __nogc (Garbage Collector) в старом синтаксисе (в .NET1.1) указывает на то, это - unmanaged-структура
__nogc struct MyCallbackWrapperUnmanaged {
    // здесь держим указатель на функцию
    fMyCallBack m_callUnmanged;
};

// эта функция берёт на вход экземпляр делегата, а возвращает указатель на функцию
fMyCallBack MakeUnmanagedCallback(MyCallback call)
{
    // создали экземпляр managed-структуры. Структура нужна как обёртка, чтобы затем Marshal-ить
    __gc struct MyCallbackWrapper *wrapper = new MyCallbackWrapper();

    // положили в неё наш экземпляр делегата
    wrapper->m_call = call;

    // создали экземпляр unmanaged-структуры
    MyCallbackWrapperUnmanaged wrapperUnmanaged;

    // промаршалим managed-структуру в unmanaged-структуру
    Marshal::StructureToPtr(wrapper, &wrapperUnmanaged, false);

    // вернули указатель, который получился в unmanaged-структуре
    return wrapperUnmanaged.m_callUnmanaged;
}


Всё это можно было бы положить в dllку на плюсах (CLR Class Libary) и, подключив к вашему C#-ому проекту, использовать с включёнными указателями (unsafe)...

Это сообщение отредактировал(а) marcusmae - 9.5.2007, 17:35


--------------------
ἀπὸ μηχανῆς θεός
PM MAIL ICQ GTalk   Вверх
Red Wind
Дата 9.5.2007, 20:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 280
Регистрация: 25.6.2004
Где: Минск

Репутация: нет
Всего: 2



Спасибо за столь подробное объяснение! Но скорее всего я немного запутался с постановкой задачи:(. Нужно полчить не указатель на делегат, а просто указатель на нейкий метод и положить этот указатель в класс IntPtr. Вот. Просто во втором фрэймворке имея возможность воспользоваться Marshal.GetFunctionPointerForDelegate это делается через делегаты.
PM MAIL ICQ   Вверх
MFSham
Дата 10.5.2007, 00:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 220
Регистрация: 28.8.2005
Где: Беларусь, Гродно

Репутация: нет
Всего: 3



Может чего полезного найдешь по этой ссылке: www.intuit.ru
--------------------
Без ветра трава неподвижна. Без программ компьютеры бесполезны.
PM MAIL   Вверх
Red Wind
Дата 10.5.2007, 22:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 280
Регистрация: 25.6.2004
Где: Минск

Репутация: нет
Всего: 2



MFSham,  спасибо за ссылку. Глянул. Может почерпну что-нибудь полезное. Но вот наткнулся на такаие методы как
System.Runtime.InteropServices.Marshal.GetManagedThunkForUnmanagedMethodPtr
System.Runtime.InteropServices.Marshal.GetUnmanagedThunkForManagedMethodPtr

Вот что написано в MSDN:

[ObsoleteAttribute("The GetManagedThunkForUnmanagedMethodPtr method has been deprecated and will be removed in a future release.", false)] 
public static IntPtr GetManagedThunkForUnmanagedMethodPtr (
    IntPtr pfnMethodToWrap,
    IntPtr pbSignature,
    int cbSignature
)

Parameters
pfnMethodToWrap
A pointer to the method to marshal. 

pbSignature
A pointer to the method signature. 

cbSignature
The number of bytes in pbSignature. 

Return Value
A pointer to the thunk that will marshal a call from the pfnMethodToWrap parameter. 

Вроде по описанию похоже на то что нужно. Но проблема в том, что нет никакой документации по ним. Пока у меня не получилось разобраться с тем как их применять. Например, как получить указатель на метод и его сигнатуру?

PM MAIL ICQ   Вверх
mr.DUDA
Дата 10.5.2007, 23:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


3D-маньяк
****


Профиль
Группа: Экс. модератор
Сообщений: 8244
Регистрация: 27.7.2003
Где: город-герой Минск

Репутация: 110
Всего: 232



А как вы сочетаете unmanaged код с managed ? Если речь о простом вызове функции из unmanaged DLL через [DllImport], то можно объявить указатель как обычный делегат и передавать его соответственно:
Код
public class Some
{
    public delegate bool CallBackPtr(int hwnd, int lParam);

    [DllImport("user32.dll")]
    public static extern int EnumWindows(CallBackPtr callPtr, int lPar); 

    void Main()
    {
        EnumWindows(new CallBackPtr(МойМетод), 0);
    }

    public static bool МойМетод(int hwnd, int lParam) 
    { 
        Console.WriteLine("Window handle is "+hwnd);
        return true;
    }
}



--------------------
user posted image
PM MAIL WWW   Вверх
marcusmae
Дата 11.5.2007, 21:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


stravaganza
**


Профиль
Группа: Участник
Сообщений: 874
Регистрация: 26.3.2006

Репутация: 22
Всего: 39



Цитата(Red Wind @  10.5.2007,  22:19 Найти цитируемый пост)
 Но проблема в том, что нет никакой документации по ним.


Обычно документация отсутствует, если метод (класс) помечен deprecated (устаревший).



--------------------
ἀπὸ μηχανῆς θεός
PM MAIL ICQ GTalk   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Прежде чем создать тему, посмотрите сюда:
mr.DUDA
THandle

Используйте теги [code=csharp][/code] для подсветки кода. Используйтe чекбокс "транслит" если у Вас нет русских шрифтов.
Что делать если Вам помогли, но отблагодарить помощника плюсом в репутацию Вы не можете(не хватает сообщений)? Пишите сюда, или отправляйте репорт. Поставим :)
Так же не забывайте отмечать свой вопрос решенным, если он таковым является :)


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, mr.DUDA, THandle.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Общие вопросы по .NET и C# | Следующая тема »


 




[ Время генерации скрипта: 0.0493 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.