Как екстернирате делегат в .Net C++

Това е вторият въпрос от поредица относно актуализирането на потребителския интерфейс от друга нишка. Опитвам се да използвам делегат, за да кажа на потребителския интерфейс да изпълни функцията за актуализиране (не трябва да се предават данни). Създадох делегат в нишката на потребителския интерфейс и го декларирах върху нишката на потребителския интерфейс:

delegate void MyDel();
public ref class Form1 : public System::Windows::Forms::Form
{
    // .....
    void testFunc()
    {
       this->local_long_textBox->Text = "Test!!!!!!!";
    }
private:
    void startUp()
    {
       MyDel^ DelInst = gcnew MyDel(this,&CotStinger::Form1::testFunc);

Бих искал да предам DelInst на друга нишка при създаване, но когато се опитам да декларирам MyDel като extern като този върху друг модул:

extern delegate MyDel;

Получавам грешката:

Грешка C2146: синтактична грешка: липсва ';' преди идентификатор 'MyDel'.

Ако опитам това

extern delegate void MyDel();

Получавам грешката:

Грешка C2144: синтактична грешка: 'void' трябва да се предхожда от ';'

И така, как да накарам другия клас да разпознае типа на делегата, за да мога да предам указателя на делегата към конструктора?


person user758362    schedule 21.06.2011    source източник


Отговори (1)


Ключовата дума delegate се използва за дефиниране на тип делегат, а не за деклариране на променлива, която случайно е някакъв тип делегат. Т.е., след като типът делегат е дефиниран, нямате нужда от ключовата дума delegate в нито един момент.

Освен това глобалните променливи от управлявани типове не са разрешени в C++/CLI; обичайното заобиколно решение е да се използва логически статичен управляван клас с публични статични членове на данни, които функционират като глобални:

delegate void MyDel();
private ref struct Globals abstract sealed
{
    static MyDel^ MyDelInstance;
};

// ...

Globals::MyDelInstance = gcnew MyDel(this, &CotStinger::Form1::testFunc);

И така, как да накарам другия клас да разпознае типа на делегата, за да мога да предам указателя на делегата към конструктора?

Същото като с всеки друг тип -- поставете го в заглавен файл, който и двата класа могат да #include.

person ildjarn    schedule 22.06.2011
comment
Копирах вашия код по-горе и получих следното съобщение: грешка C3145: 'myDelInstance': глобалната или статичната променлива може да не е управлявала тип 'CotStinger::MyDel ^' - person user758362; 22.06.2011
comment
Останалата част от съобщението е: може да не се декларира глобална или статична променлива или член на собствен тип, който препраща към обекти в gc heap - person user758362; 22.06.2011
comment
да И така, какво прави ref struct Globals abstract sealed? - person user758362; 22.06.2011
comment
@user758362 : Ако знаете C#, това е точният еквивалент на static class в C#, с изключение на това, че има публичен достъп до членове по подразбиране, а не частен. Т.е., това е управляван тип с публичен достъп до член по подразбиране, който не е позволено да бъде извлечен от или инстанциран (и така ефективно може да има само static членове с данни и членски функции). - person ildjarn; 22.06.2011
comment
Добре, включих файла Form1.h с горните декларации във втория си модул и изпитвам затруднения да го компилирам. Какъв синтаксис бих използвал във втория модул. Пише, че не е намерено. - person user758362; 22.06.2011
comment
@user758362 : Казвате, че вашият файл Form1.h съдържа дефинициите на MyDel и Globals, а някой втори файл включва Form1.h, но не можете да намерите тези дефиниции на типове? не ти вярвам ;-] - person ildjarn; 22.06.2011
comment
Разбрах. Трябваше да отделя делегатите в техен собствен .h файл. Включването на UI .h файла навсякъде създава проблеми. - person user758362; 22.06.2011
comment
@ildjarn защо не мога да декларирам делегата, точно както мога да декларирам други управлявани типове? stackoverflow.com/questions/1005892/ - person Agnel Kurian; 02.08.2013