在C ++中触发事件并在C#中处理它们 [英] Firing events in C++ and handling them in C#

查看:60
本文介绍了在C ++中触发事件并在C#中处理它们的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一台带有一些数字I / O引脚的工业计算机。制造商提供了一些C ++库和示例来处理引脚状态更改。

I have an industrial computer with some Digital I/O pins. The manufacturer provides some C++ libraries and examples to handle pin status change.

我需要将此事件集成到C#应用程序中。 AFAIK执行此操作最简单的方法是:

I need to integrate this events onto a C# application. AFAIK the most simple way to perform this is:


  1. 为制造商库制作托管的C ++ / CLI包装器,以便在发出中断时触发事件

  2. 引用并包装和处理C#部分中的事件,因为它们是正常的C#事件。

我试图用一些没有运气的模拟对象来完成这项工作。从文档来看,在我的案例中,EventHandler函数应该执行大部分肮脏的工作。遵循旧线程中可用的信息以及MSDN文档中的EventHandler示例,我最终得到了以下测试代码:

I have tried to make this work with some mock objects with no luck. From the docs, the function EventHandler should do most of the "dirty work" in my case. Following info available in old threads and the EventHandler example in the MSDN docs I ended up with this test code:

C ++ / CLI

using namespace System;

public ref class ThresholdReachedEventArgs : public EventArgs
{
public:
    property int Threshold;
    property DateTime TimeReached;
};

public ref class CppCounter
{
private:
    int threshold;
    int total;

public:
    CppCounter() {};

    CppCounter(int passedThreshold)
    {
        threshold = passedThreshold;
    }

    void Add(int x)
    {
        total += x;
        if (total >= threshold) {
            ThresholdReachedEventArgs^ args = gcnew ThresholdReachedEventArgs();
            args->Threshold = threshold;
            args->TimeReached = DateTime::Now;
            OnThresholdReached(args);
        }
    }

    event EventHandler<ThresholdReachedEventArgs^>^ ThresholdReached;

protected:
    virtual void OnThresholdReached(ThresholdReachedEventArgs^ e)
    {
        ThresholdReached(this, e);
    }
};

public ref class SampleHandler
{
public:
    static void c_ThresholdReached(Object^ sender, ThresholdReachedEventArgs^ e)
    {
        Console::WriteLine("The threshold of {0} was reached at {1}.",
            e->Threshold, e->TimeReached);
        Environment::Exit(0);
    }
};

void main()
{
    return;
    CppCounter^ c = gcnew CppCounter(20);
    c->ThresholdReached += gcnew EventHandler<ThresholdReachedEventArgs^>(SampleHandler::c_ThresholdReached);

    Console::WriteLine("press 'a' key to increase total");
    while (Console::ReadKey(true).KeyChar == 'a') {
        Console::WriteLine("adding one");
        c->Add(1);
    }
}

C#

using System;

namespace ConsoleApplication1
{
class Program
{
    static void Main(string[] args)
    {
        CppCounter cc = new CppCounter(5);
        //cc.ThresholdReached += cs_ThresholdReached; //<--This is the offending line


        Console.WriteLine("press 'a' key to increase total");
        while (Console.ReadKey(true).KeyChar == 'a')
        {
            Console.WriteLine("adding one");
            cc.Add(1);
        }
    }

    static void cs_ThresholdReached(object sender, ThresholdReachedEventArgs e)
    {
        Console.WriteLine("The threshold of {0} was reached at {1}.", e.Threshold, e.TimeReached);
        Environment.Exit(0);
    }
}

class Counter
{
    private int threshold;
    private int total;

    public Counter(int passedThreshold)
    {
        threshold = passedThreshold;
    }

    public void Add(int x)
    {
        total += x;
        if (total >= threshold)
        {
            ThresholdReachedEventArgs args = new ThresholdReachedEventArgs();
            args.Threshold = threshold;
            args.TimeReached = DateTime.Now;
            OnThresholdReached(args);
        }
    }

    protected virtual void OnThresholdReached(ThresholdReachedEventArgs e)
    {
        EventHandler<ThresholdReachedEventArgs> handler = ThresholdReached;
        if (handler != null)
        {
            handler(this, e);
        }
    }

    public event EventHandler<ThresholdReachedEventArgs> ThresholdReached;
}

  public class ThresholdReachedEventArgs : EventArgs
    {
        public int Threshold { get; set; }
        public DateTime TimeReached { get; set; }
    }
}

我在做什么错?

推荐答案

  public class ThresholdReachedEventArgs : EventArgs

代码是正确的,除了这个小故障。您不小心在C#代码中重新声明了该类。现在有两个 ,一个来自C ++ / CLI项目,另一个来自C#项目。这是一个问题,.NET中的类型标识不仅由名称空间名称和类名称决定,而且还包括它来自的程序集。

The code is correct, except for this minor glitch. You accidentally re-declared this class in your C# code. Now there are two, one from your C++/CLI project and another from your C# project. That is a problem, type identity in .NET is not just determined by the namespace name and class name, it also includes the assembly it came from.

所以这是两个不同的类型,编译器会试图告诉您它的C#版本不是正确的类型。它们具有相同的名称并不能完全帮助您解码错误消息:)

So these are two distinct types, the compiler tries to tell you that the C# version of it is not the correct one. That they have the same name doesn't exactly help you decode the error message :)

非常容易修复,只需从C#代码中删除类声明即可。现在,编译器将使用它的C ++ / CLI版本。

Very easy to fix, simply delete the class declaration from your C# code. Now the compiler will use the C++/CLI version of it.

这篇关于在C ++中触发事件并在C#中处理它们的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆