|
Компьютерный форум OSzone.net » Программирование, базы данных и автоматизация действий » Программирование и базы данных » .NET - [решено] C# to C++ dll: Маршалинг(?) массива структур |
|
.NET - [решено] C# to C++ dll: Маршалинг(?) массива структур
|
Ветеран Сообщения: 878 |
Профиль | Сайт | Отправить PM | Цитировать Всем доброе время суток!
Столкнулся с проблемой, которую не могу понять и соотвественно решить. Имеется dll, написанная на C++ (исодный код мне не известен). Обращаюсь к функциям из программы, написанной C# Имеются следующий функции (описание C++, Interop C#) //C++ SDKIMPORT_ SDKEXPORT_ DWORD sdkUpdateBoards( DWORD dwBoardsCount, sdkBoardStatus *lpBoardStatus[]); ------------------- //C# [DllImport(DLLPath, CharSet = CharSet.Auto, EntryPoint = "sdkUpdateBoards")] static public extern UInt32 sdkUpdateBoards(UInt32 BoardsCount, ref tagsdkBoardStatus[] BoardStatus); //C++ typedef struct tagsdkBoardStatus { DWORD BoardId; // Идентификатор платы DWORD OwnDriverId; // Идентификатор драйвера платы DWORD Type; // Тип платы DWORD Bus; // Тип шины платы DWORD Status; // Состояние платы DWORD BasePort; // Базовый порт платы DWORD FactoryNumber; // Номер платы DWORD FactoryVersion; // Версия платы DWORD ResourceMode; // Ресурс платы DWORD Lines; // Количество интерфейсных каналов DWORD VoiceLines; // Количество голосовых каналов DWORD ChannelsId[128]; // Идентификаторы каналов BYTE LineTypes[128]; // Типы каналов платы BYTE PossibleLineTypes[128]; // Возможные типы каналов платы BYTE LineStatus[128]; // Состояние каналов платы DWORD Cpus; // Количество сопроцессоров BYTE E1Present; // Наличие на плате мезонина Е1 DWORD PciCtrlPort; BOOL SCBus; BOOL SCBusMaster; BOOL IrqMaster; DWORD E1Lines; DWORD E1MajorVersion; DWORD E1MinorVersion; DWORD E1STS; }sdkBoardStatus; //C# public struct tagsdkBoardStatus { public UInt32 BoardId; // Идентификатор платы public UInt32 OwnDriverId; // Идентификатор драйвера платы public UInt32 Type; // Тип платы public UInt32 Bus; // Тип шины платы public UInt32 Status; // Состояние платы public UInt32 BasePort; // Базовый порт платы public UInt32 FactoryNumber; // Номер платы public UInt32 FactoryVersion; // Версия платы public UInt32 ResourceMode; // Ресурс платы public UInt32 Lines; // Количество интерфейсных каналов public UInt32 VoiceLines; // Количество голосовых каналов [MarshalAs(UnmanagedType.ByValArray, SizeConst = 128)] public UInt32[] ChannelsId; // Идентификаторы каналов [MarshalAs(UnmanagedType.ByValArray, SizeConst = 128)] public byte[] LineTypes; // Типы каналов платы [MarshalAs(UnmanagedType.ByValArray, SizeConst = 128)] public byte[] PossibleLineTypes; // Возможные типы каналов платы [MarshalAs(UnmanagedType.ByValArray, SizeConst = 128)] public byte[] LineStatus; // Состояние каналов платы public UInt32 Cpus; // Количество сопроцессоров public byte E1Present; // Наличие на плате мезонина Е1 public UInt32 PciCtrlPort; public bool SCBus; public bool SCBusMaster; public bool IrqMaster; public UInt32 E1Lines; public UInt32 E1MajorVersion; public UInt32 E1MinorVersion; public UInt32 E1STS; }; //C# [MarshalAs(UnmanagedType.LPArray, SizeConst = 32)] public static tagsdkBoardStatus[] BoardStatus; //Статус плат BoardStatus = new tagsdkBoardStatus[2]; f = sdkUpdateBoards(BoardsCount, ref BoardStatus); ------- Извиняюсь, за столько скомконное изложение, но по окончанию рабочего дня мозг медленно плавится ((( |
|
Отправлено: 17:57, 20-01-2010 |
Ветеран Сообщения: 878
|
Профиль | Сайт | Отправить PM | Цитировать Господа, очень надеюсь на вашу помощь!
Хех, я смотрю я уже не Контрибьютор ) |
Отправлено: 10:19, 21-01-2010 | #2 |
Для отключения данного рекламного блока вам необходимо зарегистрироваться или войти с учетной записью социальной сети. Если же вы забыли свой пароль на форуме, то воспользуйтесь данной ссылкой для восстановления пароля. |
Ветеран Сообщения: 878
|
Профиль | Сайт | Отправить PM | Цитировать Спасибо всем! вопрос снят.
Нашелся более лаконичный метод. Небольшой сниппет для будущих поколений: 1. Convert IntPtr to array of struct(для поиска IntPtr2array) public static Array PtrToArray(Type structureType,IntPtr arrayPtr,int length) { if (structureType == null) throw new ArgumentNullException("structureType"); if (!structureType.IsValueType) throw new ArgumentException("Only struct types are supported.", "structureType"); if (length < 0) throw new ArgumentOutOfRangeException("length", length, "length must be equal to or greater than zero."); if (arrayPtr == IntPtr.Zero) return null; int size = Marshal.SizeOf(structureType); Array array = Array.CreateInstance(structureType, length); for (int i = 0; i < length; i++) { IntPtr offset = new IntPtr((long)arrayPtr + (size * i)); object value = Marshal.PtrToStructure(offset, structureType); array.SetValue(value, i); } return array; } А вообще было приятно снова посетить наш форму. опять таки давно не был здесь *Сниппет не относится напрямую к поставленному вопросы в теме |
Отправлено: 13:58, 21-01-2010 | #3 |
Ветеран Сообщения: 5624
|
Профиль | Отправить PM | Цитировать Цитата XCodeR:
|
|
------- Отправлено: 02:13, 22-01-2010 | #4 |
Ветеран Сообщения: 878
|
Профиль | Сайт | Отправить PM | Цитировать Delirium,
очень - очень ( |
|
Отправлено: 10:18, 22-01-2010 | #5 |
Участник сейчас на форуме | Участник вне форума | Автор темы | Сообщение прикреплено |
| |||||
Название темы | Автор | Информация о форуме | Ответов | Последнее сообщение | |
Ошибка - [решено] точка входа в процедуру getperfomanceInfo не найдена в библиотеке DLL PSAPI.DLL | aksex | Microsoft Windows 2000/XP | 11 | 31-03-2015 19:43 | |
Для чего нужны dll библиотеки или Учимся редактировать dll | Ban_vam_Dam | Флейм | 5 | 31-07-2009 17:41 | |
Разное - [решено] dwmapi.dll; mpr.dll; shlwapi.dll | Reset5 | Microsoft Windows 2000/XP | 2 | 14-06-2008 16:31 | |
C/C++ - Сравнение структур в языке 'С' | t0lkman | Программирование и базы данных | 1 | 21-04-2008 14:30 | |
запись структур в VС++ | Drey | Программирование и базы данных | 17 | 03-03-2004 02:27 |
|