Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Общие вопросы по .NET и C# > Передача параметра в COM метод, C#


Автор: nextzi0 14.3.2013, 14:35
В общем есть подключенный к проекту COM объект, в нужном мне COM классе есть метод. Сигнатура: mScan(ref byte pDevList):void. При попытке передать параметр, выскакивает AccesViolation (попытка чтения или записи в защищенную память). Я так понял, нужно юзать P/Invoke? Как в таком случае передать параметр?

Автор: mihryak 14.3.2013, 16:09
попробуй поиграться с STA/MTA, ошибки маршалинга нередко имеют корни в этом

Автор: nextzi0 15.3.2013, 09:05
Пробовал, не  в этом дело. Дело в том, что не могу передать адрес в куче как параметр в COM метод, т.к. идет несовпадение типов

Автор: DarkDragon 15.3.2013, 10:28
может попробовать так:
mScan([MarshalAs(UnmanagedType.LPArray)]ref byte pDevList)

или использовать unsafe код вида:
mScan(byte * pDevList)

Автор: nextzi0 15.3.2013, 15:51
MarshalAs так не используется, у меня же нет атрибута [DllImport()]
С небезопасным кодом тоже ничего не выходит. Застрял на ref byte. Нативная функция принимает параметр unsigned char *

Автор: mihryak 15.3.2013, 17:36
так может выделить память через какой-нибудь Marshal.AllocHGlobal, положить туда данные и передать указатель?

Автор: DarkDragon 15.3.2013, 20:43
Цитата(nextzi0 @  15.3.2013,  15:51 Найти цитируемый пост)
MarshalAs так не используется, у меня же нет атрибута [DllImport()]

DllImport - это прямой импорт функции из неуправляемой библиотеки. MarshalAs указывает как интерпретировать (передавать, получать) параметр и данные в функции между управляемым и неуправляемым кодом. Так что не понял почему MarshalAs не может быть использован без DllImport, вроде как работаете с неуправляемым COM объектом.

Автор: DarkDragon 15.3.2013, 22:15
Еще можно попробовать так: 
Код

mScan([Out] byte[] pDevList)
...
byte[] bData = new byte[1];
mScan(bData);

Автор: nextzi0 16.3.2013, 20:10
Цитата(mihryak @ 15.3.2013,  17:36)
так может выделить память через какой-нибудь Marshal.AllocHGlobal, положить туда данные и передать указатель?

Ну мне достаточно ее выделить и передать указатель, я пробовал так уже, ругается на несовместимость типов, как только я не приводил

Добавлено через 2 минуты и 12 секунд
DarkDragon, ну этот код mScan([MarshalAs(UnmanagedType.LPArray)]ref byte pDevList) точно не работает, иначе мне надо описать эту ф-ию с другим типом параметров и потом ее вызывать... ? Попробую

Автор: DarkDragon 16.3.2013, 21:05
nextzi0, попробуйте еще с атрибутом [Out]byte[]. Я проверял работу на WinAPI функции - работает, возможно еще возвращается не один байт а скажем несколько, тогда возможно выходит за границы и провоцирует Access Violation?

Автор: nextzi0 18.3.2013, 06:57
Argument is 'out' while parameter is declared as 'ref'.

Вот этот код в C++ работает:

Код

unsigned char *pTest[10];
for (i=0; i<10; i++)
            pTest[i] = (unsigned char *)malloc(100);

bootCOM->mScan((unsigned char *)pTest);

i= 0;
while (pTest[i] != 0)
{
    printf("Device %d = %s\n\r", i, pTest[i]);
    i++;
}


Ф-я сканирует подключенные устройства и заполняет выделенную память названиями устройств. Под каждое название д.б. выделено > 80 байт (в описании к dll).

Вся проблема в ref byte... Это, по сути, неверный параметр для данной ф-ии в C#

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)