2016-07-18 2 views
-1

я хотел бы преобразовать этот код (рабочий код в C#) в C++/CLIДополнительные параметры для FileSystemEventHandler в C++/CLI

 static private void onChange(object s, FileSystemEventArgs e, string customArg) 
    { 
     Console.WriteLine(e.FullPath); 
     Console.WriteLine(customArg); 
    } 

    static void Main(string[] args) 
    { 
     string customArg = "myCustomArg"; 

     FileSystemWatcher watcher = new FileSystemWatcher(); 
     watcher.Path = "G:\\"; 
     watcher.IncludeSubdirectories = true; 
     watcher.NotifyFilter = NotifyFilters.LastWrite; 
     watcher.EnableRaisingEvents = true; 

     // i cannot convert this line in c++/cli 
     watcher.Changed += (s, e) => onChange(s, e, customArg); 

     Console.Read(); 
    } 

есть мой код в C++/CLI

void FileWatcher::onChanged(Object^ source, FileSystemEventArgs^ e, String^ customArg) 
{ 
    Console::WriteLine(e->FullPath); 
    Console::WriteLine(customArg); 
} 

int main(int argc, char* argv[]) 
{ 
    FileSystemWatcher watcher->Path = "G:\\"; 
    watcher->IncludeSubdirectories = true; 
    watcher->NotifyFilter = static_cast<System::IO::NotifyFilters> (NotifyFilters::LastWrite); 

    String^ customArg = gcnew String("myArg"); 

    // this line not compile 
    watcher->Changed += (s, e) = > onChange(s, e, customArg); 
    // 
} 

я пытался использовать функцию лямбда, как этот

watcher->Changed += [](Object^ s, FileSystemEventArgs^ e, String^ c) -> void { OnChange(s, e, c); }; 

, но это не работает, вероятно, делает неправильно

+0

По http://stackoverflow.com/questions/2777445/lambda-expressions-as-clr-net-delegates-event-handlers-in-visual-c-2010 вы не можете назначить лямбда как делегат –

ответ

1

Кажется, что вы не можете сделать это через лямбда, поэтому вам нужно создать класс, который представляет собой обработчик событий, что-то похожее на это.

#using <System.dll> 

using namespace System; 
using namespace System::IO; 

void GlobalOnChanged(Object^ source, FileSystemEventArgs^ e, String^ customArg) 
{ 
    Console::WriteLine(e->FullPath); 
    Console::WriteLine(customArg); 
} 

public ref class Invoker 
{ 
public: 
    Invoker(String^ customArg) : customArg_(customArg) 
    { 

    } 
    void OnChanged(Object^ source, FileSystemEventArgs^ e) 
    { 
     GlobalOnChanged(source, e, customArg_); 
    } 

private: 
    String^ customArg_; 
}; 

int main(int argc, char* argv[]) 
{ 
    FileSystemWatcher^ watcher = gcnew FileSystemWatcher; 
    watcher->Path = "C:\\"; 
    watcher->IncludeSubdirectories = true; 
    watcher->NotifyFilter = static_cast<System::IO::NotifyFilters> (NotifyFilters::LastWrite); 
    String^ customArg = gcnew String("myArg"); 
    watcher->Changed += gcnew FileSystemEventHandler(gcnew Invoker(customArg), &Invoker::OnChanged); 
} 
+0

спасибо, что он работает !!!, – rbglobal

+0

Обратите внимание, что когда вы пишете лямбду в C#, компилятор C# производит нечто * очень похожее на это. Класс 'Invoker' имел бы поля для дополнительных параметров, которые должны быть переданы этому методу, как показано здесь, и для метода, который должен быть вызван. –

+0

@ David Я думал, что ты сумасшедший, потому что не просто сделал захват лямбда customArg. Оказывается, в C++/cli нет управляемых лямбдов. Гигантская дыра в языке. – tukra

Смежные вопросы