Обратный вызов из Delphi DLL в C # - работает только в режиме ожидания winform или с использованием app.doevents? - PullRequest
1 голос
/ 14 апреля 2011

Я сдаюсь, я должен написать и спросить;Я использую неуправляемую DLL, написанную на Delphi, которая асинхронно вызывает (без параметров) обратный вызов, передаваемый ей всякий раз, когда происходит событие в оборудовании, которое разработано для мониторинга.

То, что я делаю в C #, это то, что я держустатическая ссылка на созданный делегат, который затем передается в качестве параметра методу start на стороне Delphi.Это говорит DLL, чтобы она уведомляла меня, используя обратный вызов, всякий раз, когда появляются новые данные для извлечения, используя метод GetData.

Все работает отлично, очень хорошо, пока я не попытаюсь сделать то же самое в консольном приложении или в службе Windows.Или если я создаю и вызываю связанные с DLL методы в отдельном потоке, не позволяя этому потоку вращаться, выполняя Application.DoEvents ().Обычно люди с похожими проблемами, похоже, имели проблемы с GC или соглашениями о вызовах, но (попытались) обезопасить себя от проблем GC, оставив делегата без каких-либо дополнительных подсказок о том, как решить эту проблему.

Я предполагаю, что упускаю что-то первостепенное в том, как CLR вызывает мои обратные вызовы после того, как DLL вызывает предоставляемый thunk для подключения к моему обработчику обратного вызова.

Внешний вид объявлений моего импорта 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

1 Ответ

1 голос
/ 14 апреля 2011

Трудно сказать, не видя нативный код, но я предполагаю, что код на нативной стороне зависит от цикла обработки сообщений в потоке, который вызывает Start? например потому что он использует TTimer или аналогичный?

После возврата вызова Start есть только 2 способа выполнения любого кода внутри этой DLL. Либо был запущен новый поток, либо был зарегистрирован таймер или какой-либо другой механизм, который зависит от сообщений в окне.

EDIT:

Другая возможность:

Если собственная библиотека DLL использует межпроцессный COM в STA (однопотоковая квартира), то COM зависит от работающей петли сообщений.

...