Имя пользователя:
Пароль:  
Помощь | Регистрация | Забыли пароль?  | Правила  

Компьютерный форум OSzone.net » Программирование, базы данных и автоматизация действий » Программирование и базы данных » .NET - [решено] C# to C++ dll: Маршалинг(?) массива структур

Ответить
Настройки темы
.NET - [решено] C# to C++ dll: Маршалинг(?) массива структур

Аватара для XCodeR

Ветеран


Сообщения: 878
Благодарности: 53

Профиль | Сайт | Отправить 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);
В итоге в BoardStatus только 1 элемента, когда должно быть 2.
-------

Извиняюсь, за столько скомконное изложение, но по окончанию рабочего дня мозг медленно плавится (((

Отправлено: 17:57, 20-01-2010

 

Аватара для XCodeR

Ветеран


Сообщения: 878
Благодарности: 53

Профиль | Сайт | Отправить PM | Цитировать


Господа, очень надеюсь на вашу помощь!
Хех, я смотрю я уже не Контрибьютор )

Отправлено: 10:19, 21-01-2010 | #2



Для отключения данного рекламного блока вам необходимо зарегистрироваться или войти с учетной записью социальной сети.

Если же вы забыли свой пароль на форуме, то воспользуйтесь данной ссылкой для восстановления пароля.


Аватара для XCodeR

Ветеран


Сообщения: 878
Благодарности: 53

Профиль | Сайт | Отправить 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;
        }
Если интересует, то могу оформить небольшую статью по маршалингу типов и вообще использованию сишных библиотек под .Net.

А вообще было приятно снова посетить наш форму. опять таки давно не был здесь

*Сниппет не относится напрямую к поставленному вопросы в теме

Отправлено: 13:58, 21-01-2010 | #3


Аватара для Delirium

Ветеран


Сообщения: 5624
Благодарности: 936

Профиль | Отправить PM | Цитировать


Цитата XCodeR:
Хех, я смотрю я уже не Контрибьютор ) »
XCodeR, видать очень давно не появлялся

-------

Пройденные курсы:
[Microsoft №10174 Sharepoint], [SharePoint]
Мои проекты:[CheckAdmins], [NetSend7], [System Uptime], [Remote RAdmin LogViewer],[Netdom GDI], [Holidays - напоминалка о днях рождения]

А я офис-гуру :)


Отправлено: 02:13, 22-01-2010 | #4


Аватара для XCodeR

Ветеран


Сообщения: 878
Благодарности: 53

Профиль | Сайт | Отправить PM | Цитировать


Delirium,
очень - очень (

Отправлено: 10:18, 22-01-2010 | #5



Компьютерный форум OSzone.net » Программирование, базы данных и автоматизация действий » Программирование и базы данных » .NET - [решено] C# to C++ dll: Маршалинг(?) массива структур

Участник сейчас на форуме Участник сейчас на форуме Участник вне форума Участник вне форума Автор темы Автор темы Шапка темы Сообщение прикреплено

Похожие темы
Название темы Автор Информация о форуме Ответов Последнее сообщение
Ошибка - [решено] точка входа в процедуру 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




 
Переход