#c# #c #dll #marshalling
#c# #c #dll #Сортировка
Вопрос:
у меня возникли некоторые проблемы в моем проекте.
Я использую c .скомпилированная dll (у меня нет возможности изменить ее, перекомпилировать или изменить) у меня есть файл .h, где есть некоторая (плохо документированная) информация. Эта библиотека dll используется для взаимодействия с устройством, подключенным через USB. Устройство правильно сконфигурировано, и с помощью функции, предоставляемой dll, у меня есть абсолютная уверенность в том, что оно правильно отвечает на вызов dll. Сортировка с c и c # довольно проста, пока мне не придется использовать обратный вызов для регистрации на какое-либо событие, генерируемое устройством.
Это важная часть c .h, которую я должен использовать в c # (первое и второе события являются поддельными именами)
//First Event data
typedef struct tagFIRST_EVENT {
int a;
int b;
int c;
} FIRST_EVENT;
//SecondEvent data
typedef struct tagSECOND_EVENT {
int e;
int f;
} SECOND_EVENT;
//first event callback?
typedef void (CALLBACK *FIRTS_EVENT_LISTENER)(FIRST_EVENT *event, void *userData);
//second event callback?
typedef void (CALLBACK *SECOND_EVENT_LISTENER)(SECOND_EVENT *event, void *userData);
//Register to all given callback in the struct LISTENER
int WINAPI RegisterEvents(LISTENER *listenerGroup );
typedef struct tagLISTENER {
FIRTS_EVENT_LISTENER first_listener;
SECOND_EVENT_LISTENER second_listener;
void * userData;
} LISTENER;
У меня возникли некоторые проблемы с сортировкой, чтобы иметь c .dll вызывает мои функции c #, которые я определил для обработки события, генерируемого устройством.
Я следовал многим найденным примерам, но у меня не было возможности использовать эти функции надлежащим образом. В основном сбой приложения c # без какой-либо дополнительной информации (я думаю, потому что ошибка находится в c dll, и я не могу поймать ошибку).
Могу ли я привести пример реализации, учитывая приведенный выше фрагмент кода?
Я глубоко искал и нашел только похожий вопрос, но ни один из них не смог мне помочь. Я здесь для любых разъяснений, спасибо за совет!
Комментарии:
1. Вы не упомянули, какие у вас проблемы…
2. Я прервал эту вечеринку, извините. Я отредактирую сообщение, чтобы ответить на ваш вопрос.
3. Сохраняете ли вы экземпляр делегата обработчика до тех пор, пока больше обратных вызовов не ожидается?
4. Как это можно сделать? Я видел какой-то пример на c , но подумал, что это не главное (возможно, я подумал, что это плохо), могу ли я привести небольшой пример?
Ответ №1:
Ну, я не знаю, сколько маршалинга вы выполнили, поэтому я предполагаю, что вы создали бинарно-совместимые типы в C # для FirstEvent
и SecondEvent
типы данных.
Для указателей на функции все, что вам нужно, это IntPtr
.
После всего этого (что я расширю, если вы не создали типы, совместимые с двоичными файлами), все, что вам нужно сделать, это создать делегат, который сам по себе совместим с двоичными файлами:
delegate void FirstEventListener(ref FirstEvent firstEvent, IntPtr userData);
delegate void SecondEventListener(ref SecondEvent secondEvent, IntPtr userData);
затем вы можете создать экземпляр делегата для фактического обработчика и использовать [Marshal.GetFunctionPointerForDelegate](http://msdn.microsoft.com/en-us/library/at4fb09f.ASPX)
для получения указателя (как IntPtr
),
Не забывайте поддерживать этот экземпляр делегата в рабочем состоянии (т.Е. Хранить ссылку на него) до тех пор, пока может быть вызван обратный вызов.
Комментарии:
1. Большое спасибо, я протестирую и посмотрю!! Я опубликую некоторые варианты моего решения на c #, если я не смогу это исправить.
2. Решаемая большое спасибо, я делал одну СЕРЬЕЗНУЮ ошибку. Две структуры (FirstEvent и SecondEvent) не были основаны на ref. Еще раз спасибо!