从Delphi DLL到c#的回调-仅在空闲的winform或使用app.doevents中工作

本文关键字:winform app 工作 doevents DLL Delphi 回调 | 更新日期: 2023-09-27 17:50:21

我放弃了,我得写信问;我使用的是用Delphi编写的非托管DLL,它异步调用传递给它的(无参数)回调,每当在硬件中发生事件时,它被开发来监视。

我在c#中所做的是保持对已创建委托的静态引用,然后将其作为参数传递给Delphi端的start方法。这告诉DLL使用回调通知我,每当有新数据要获取时,使用GetData方法。

一切都很好,真的很好,直到我尝试在控制台应用程序或windows服务中做完全相同的事情。或者,如果我在一个单独的线程上创建并调用DLL相关的方法,而不让该线程执行Application.DoEvents()。通常,有类似问题的人似乎在GC或调用约定方面遇到了问题,但是(试图)通过保持委托ref不变来防止GC问题,而没有进一步的线索来解决这个问题。

我假设我在DLL调用连接到我的回调处理程序后CLR如何调用我的回调中遗漏了一些重要的东西。

我的DLL导入的声明是这样的:

    [DllImport("TheDelphiApi.dll", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Ansi)]
    private static extern UInt32 Start(MulticastDelegate callback);
    [DllImport("TheDelphiApi.dll", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Ansi)]
    private static extern void GetData(byte[] recdata);
    public delegate void EngineCallbackHandler();                     
    private static EngineCallbackHandler engineCallback;

和设置回调的调用:

        UInt32 result = Start(engineCallback);

有线索吗?为什么需要DoEvents?任何反馈都是非常感激的,一直在尝试研究这个几天了,没有任何进展的迹象。/J

从Delphi DLL到c#的回调-仅在空闲的winform或使用app.doevents中工作

在没有看到本机代码的情况下很难判断,但我认为本机端的代码依赖于调用Start?例如,因为它使用TTimer或类似的?

一旦对Start的调用返回,只有两种方法可以在DLL中执行代码。要么是启动了一个新线程,要么是注册了一个计时器,要么是注册了其他依赖于窗口消息的机制。

编辑:

另一种可能性:

如果本机DLL在STA(单线程公寓)中使用跨进程COM,则COM依赖于工作消息循环。