Я пишу приложение C # в Windows CE 6 для мониторинга 3G-модема. Приложение будет вызывать функции в C DLL для доступа к модему.
При запуске приложение C # вызывает эту функцию для создания нового соединения:
[DllImport("swmodem.dll", CallingConvention = CallingConvention.Winapi)]
public static extern int CreateDataConnection(EVENT_CALLBACK callback);
EVENT_CALLBACK определяется как:
public delegate void EVENT_CALLBACK(int e, IntPtr data);
Также определена структура данных:
[StructLayout(LayoutKind.Sequential)]
public struct ECIO_INFO
{
public UInt32 ecio1; /*!< Primary scramble code */
public UInt32 ecio2; /*!< Received signal code power */
public UInt32 ecio3; /*!< Energy per chip per power density */
}
В C DLL указатель функции передается в CreateDataConnection () для обновления состояния модема.
int CreateDataConnection(EVENT_CALLBACK ecb)
{
.
.
fEventCallback = ecb;
// Create a connection
.
.
}
После создания соединения DLL вызовет функцию обратного вызова для обновления состояния модема, например, EC / IO (отношение принятой энергии пилот-сигнала).
Обычно, когда изменяется ECIO, вызывается функция обратного вызова для передачи данных ECIO в приложение C #:
В C DLL:
void ProcessNotification(EVENT_CALLBACK fEventCallback)
{
ECIO_INFO ecio_info;
ecio_info.ecio1 = ecio_info.ecio2 = ecio_info.ecio3 = 0;
if(data.nNumOfCells>0)
ecio_info.ecio1 = data.arCellInfo[0].nEcIo;
if(data.nNumOfCells>1)
ecio_info.ecio2 = data.arCellInfo[1].nEcIo;
if(data.nNumOfCells>2)
ecio_info.ecio3 = data.arCellInfo[2].nEcIo;
if(data.nNumOfCells>0)
fEventCallback(ME_RSCP_ECIO, &ecio_info);
}
В приложении C # функция обратного вызова определяется как:
private void ModemEventCallback(int e, IntPtr data)
{
.
.
Modem.ECIO_INFO new_reinfo = new Modem.ECIO_INFO();
new_reinfo = (Modem.ECIO_INFO)Marshal.PtrToStructure(
data, typeof(Modem.ECIO_INFO));
.
.
}
Теперь проблема приходит. Когда программа запускается, все в порядке, соединение создается нормально и обновляется EC / IO. но после нескольких часов работы обновление EC / IO останавливается. После теста я обнаружил, что он останавливается при вызове обратного вызова:
fEventCallback(ME_RSCP_ECIO, &ecio_info);
Я не знаю, что здесь пошло не так. Возможно, передача указателя на функцию в C # DLL вызывает просто неправильный способ сделать это, или в коде скрыта какая-то ошибка?