Roof
Гость
|
|
« : 13-02-2007 16:58 » |
|
Еще вопрос как быть, если функция в Dll имеет такой вид:
err = GetAmplifyADC(typeDevice, numberDSP, 0, &lifyADC0);
на С++ переменная amplifyADC0 обявлена как double
я так понимаю, что функции надо передать адрес этой переменной т.к стоит &
как это сделать на С#?
|
|
|
Записан
|
|
|
|
nikedeforest
|
|
« Ответ #1 : 13-02-2007 17:12 » |
|
Кхе, простите, но врят ли с помощью dllImport. Утилита tlbimp.exe используется, если речь идет о раннем связывании. В случае позднего связывания и она не нужна. По вопросу. В сборке, твоя функция будет представлена так, что у последнего параметра будет стоять ключевое слово ref. Но когда ты будешь передавать параметр, то тебя это не должно беспокоить. Ты просто подставишь туда переменную. По идеи так.
|
|
|
Записан
|
ещё один вопрос ...
|
|
|
Roof
Гость
|
|
« Ответ #2 : 13-02-2007 17:22 » |
|
Некоторые функции уже импортировал, работают, только как вызвать функцию которая принимает в качестве аргумента адрес переменной? [DllImport("Adc.dll")] public static extern int GetAmplifyADC(int typeDevice, int numberDSP, int numberChannel, ref amplifyADC0); так? в идеале по адресу переменной amplifyADC0 записывается значение.
|
|
|
Записан
|
|
|
|
nikedeforest
|
|
« Ответ #3 : 13-02-2007 17:33 » |
|
Ааа, извини, я тебя не так понял. То что я написал про утилиту, это я не к месту. Да, попробуй так, должно получиться.
|
|
|
Записан
|
ещё один вопрос ...
|
|
|
Roof
Гость
|
|
« Ответ #4 : 13-02-2007 17:46 » |
|
вроде получилось, тогда следующий вопросик, если тебя не затруднит, как быть если функция требует в качестве параметра указатель?
|
|
|
Записан
|
|
|
|
nikedeforest
|
|
« Ответ #5 : 13-02-2007 17:56 » |
|
Так же
|
|
|
Записан
|
ещё один вопрос ...
|
|
|
Roof
Гость
|
|
« Ответ #6 : 13-02-2007 18:17 » |
|
есть в С++ такая хрень, она не нужна, но в этой структуре есть штука (выделил) typedef struct _userBITMAP { LONG bmType; LONG bmWidth; LONG bmHeight; LONG bmWidthBytes; WORD bmPlanes; WORD bmBitsPixel; ULONG cbSize; /* [size_is] */ byte pBuffer[ 1 ]; } userBITMAP;
Далее в cpp:
pBuffer16ADC = (short*) pBuffer;
как это записать на C#, я извеняюсь может я уже туплю, много работаю...
|
|
|
Записан
|
|
|
|
nikedeforest
|
|
« Ответ #7 : 13-02-2007 18:27 » |
|
А что именно не ясно. Тебя смущает приведение типов? Или тебя смущает именно то, что функция возвращает указатель?
|
|
|
Записан
|
ещё один вопрос ...
|
|
|
Roof
Гость
|
|
« Ответ #8 : 13-02-2007 18:38 » |
|
Просто, как я понимаю, в памяти организуется буфер, куда АЦП складывает дискретные отсчеты, в С++ это делается через указатель, который является одним из параметров функции, а вот как этот буфер реализовать на C#? Возможно ли сделать массив типа float и попытаться его запихнуть в функцию?
|
|
|
Записан
|
|
|
|
nikedeforest
|
|
« Ответ #9 : 13-02-2007 18:42 » |
|
Я сейчас напишу кое что, если ты это знаешь, то извини, не хотел обидеть. Дело в том, что тип short 16 бит в себе содержит, а тип byte 8 бит В структуре выделяется массив типа byte из двух элементов. Каждый элемент по 8 бит. А вот теперь смотри. Вот эта операция pBuffer16ADC = (short*) pBuffer; присваивает указателю на тип short ( переменная pBuffer16ADC ) адрес первого элемента массива типа byte. Надеюст ты понял. Если не понял, то объясню по -другому. А если знал, то извини.
|
|
|
Записан
|
ещё один вопрос ...
|
|
|
nikedeforest
|
|
« Ответ #10 : 13-02-2007 18:49 » |
|
Это т.е. в самой функции вот такая херь происходит??? pBuffer16ADC = (short*) pBuffer;
Если да, то надо думать. Пока в голову ничего не лезет.
|
|
|
Записан
|
ещё один вопрос ...
|
|
|
Roof
Гость
|
|
« Ответ #11 : 13-02-2007 18:58 » |
|
С этим понятно, а вот еще такая хрень, в С++ while(!kbhit()) { сдесь АЦП собирает данные, делается проверка, если новые данные в АЦП не поступили, то выход. } kbhit()- вот такой непонятный зверь. иду к определению получаю фаил conio.h #endif /* _M_IX86 */ _CRT_NONSTDC_DEPRECATE(_getch) _CRTIMP __checkReturn int __cdecl getch(void); _CRT_NONSTDC_DEPRECATE(_getche) _CRTIMP __checkReturn int __cdecl getche(void); _CRT_NONSTDC_DEPRECATE (_kbhit) _CRTIMP __checkReturn int __cdecl kbhit(void); что это? и с чем его едят? можно еще
|
|
|
Записан
|
|
|
|
nikedeforest
|
|
« Ответ #12 : 13-02-2007 19:21 » |
|
_DERIVED_::InternalAcceptingInput Queries whether an input stream can accept more input. The derived class must declare and implement this method.
Syntax
HRESULT InternalAcceptingInput( DWORD dwInputStreamIndex );
Parameters
dwInputStreamIndex
Index of an input stream.
Return Value
Returns S_OK if the input stream can accept input, or S_FALSE otherwise.
Короче, забей . Представь, что это int kbhit (void) С этим понятно, а вот еще такая хрень, в С++
что, неужели стой фигней - pBuffer16ADC = (short*) pBuffer; - разобрался? У меня по этому поводу есть мыслишка, но пока не особо представляю как ее реализовать. Думается мне, что надо передавать туда свой класс. Переопределить в нем индексацию и сделать так, чтобы при обращении к объекту возвращалось значение short состоящее из двух элементов (как заставить коструктор вернуть значение? ). Но надо экспериментировать.
|
|
« Последнее редактирование: 13-02-2007 19:25 от nikedeforest »
|
Записан
|
ещё один вопрос ...
|
|
|
Roof
Гость
|
|
« Ответ #13 : 13-02-2007 19:57 » |
|
nikedeforest, огромное спасибо, на сегодня хватит, голова болит, пойду пить пиво!
|
|
|
Записан
|
|
|
|
nikedeforest
|
|
« Ответ #14 : 13-02-2007 20:47 » |
|
Мда, хорошего по немножку . Не забыть завтра еще покапаться, самому интересно
|
|
|
Записан
|
ещё один вопрос ...
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #15 : 13-02-2007 21:26 » |
|
nikedeforest, заставить коструктор вернуть значение через указатель
|
|
|
Записан
|
|
|
|
Roof
Гость
|
|
« Ответ #16 : 14-02-2007 05:03 » |
|
остался последний вопрос...а может и нет
дело в следующем, импортирую функции из Dll(C++) для работы с АЦП. в оперативной памяти создается буфер, куда АЦП скидывает дискретные отсчеты, есть функция, которая возвращает размер этого буфера и его место нахождение для моего случая получаем: sizeBuffer=108546(отсчеты по 16 бит) и место нахождение в ОЗУ pBuffer= 68387968 ну типа УРА, есть буфер, а как получить доступ к содержимому на C#? я так думаю, что это будет массив, только как ему присвоить значения из ОЗУ
|
|
|
Записан
|
|
|
|
nikedeforest
|
|
« Ответ #17 : 14-02-2007 06:07 » |
|
Стоп, я что-то уже не понимаю. Это таже задача, что была до этого или уже другая?
|
|
|
Записан
|
ещё один вопрос ...
|
|
|
Roof
Гость
|
|
« Ответ #18 : 14-02-2007 06:10 » |
|
нет, движемся вперед, и это наверное последнее,что мне осталось решить сейчас пробую что-нибудь с intPtr придумать
|
|
|
Записан
|
|
|
|
nikedeforest
|
|
« Ответ #19 : 14-02-2007 06:47 » |
|
А как ты ту задачу решил? Интересно же ...
|
|
|
Записан
|
ещё один вопрос ...
|
|
|
Roof
Гость
|
|
« Ответ #20 : 15-02-2007 03:16 » |
|
Честно говоря, я ее не решил, а перепоручил по честному у меня нет на это времени Смысл в слудующем, приобрел АЦП SigmaUSB16, а функции для работы с ним все в dll на VC++ 6.0 вот и пытаюсь их приспособить под C#... с перемеными успехами ...
|
|
|
Записан
|
|
|
|
nikedeforest
|
|
« Ответ #21 : 15-02-2007 10:14 » |
|
Короче, предыдущая задача решается все таки тем, что ты pBuffer должен сделать массивом типа byte (такой тип в .НЕТ есть). Вот. По поводу последней пока еще не думал.
|
|
|
Записан
|
ещё один вопрос ...
|
|
|
MOPO3
Ай да дэдушка! Вах...
Команда клуба
Offline
Пол:
Холадна аднака!
|
|
« Ответ #22 : 15-02-2007 13:31 » |
|
сейчас пробую что-нибудь с intPtr придумать
Хммм... Что то не совсем я понял что тут творится. А насчёт IntPtr, так эта структура для того и существует чтобы представлять pointer или handle. A platform-specific type that is used to represent a pointer or a handle.
|
|
|
Записан
|
MCP, MCAD, MCTS:Win, MCTS:Web
|
|
|
nikedeforest
|
|
« Ответ #23 : 15-02-2007 16:39 » |
|
Мороз, давн тебя не видно было, хорошо, что зашел. Можешь подсказать русскоязычную литературу, где бы расписывались подробно все (или большинство) тонкостей dllImport? Я пока читал только Троэлсена и местами Шилдта.
|
|
|
Записан
|
ещё один вопрос ...
|
|
|
Dimka
Деятель
Команда клуба
Offline
Пол:
|
|
« Ответ #24 : 15-02-2007 17:50 » |
|
А насчёт IntPtr, так эта структура для того и существует чтобы представлять pointer или handle. Такие значения в ней будут храниться. А вот как их оттуда извлечь и проинтерпретировать? Ведь код .NET безопасный, и напрямую работать с адресами "низя". Допустим, возвращается из DLL указатель типа "void *" (любимое дело в WinAPI) на некоторую структуру. Получим в .NET этот IntPtr. И как с его помощью вытащить структуру из памяти - создать по правилам .NET и с управлением сборщиком мусора копию этой структуры, чтобы её использовать?
|
|
|
Записан
|
Программировать - значит понимать (К. Нюгард) Невывернутое лучше, чем вправленное (М. Аврелий) Многие готовы скорее умереть, чем подумать (Б. Рассел)
|
|
|
vins
Гость
|
|
« Ответ #25 : 15-02-2007 19:24 » |
|
И как с его помощью вытащить структуру из памяти - создать по правилам .NET и с управлением сборщиком мусора копию этой структуры, чтобы её использовать? В сигнатуре метода тип аргумента объявляется не как IntPtr, а как структура, описанная на C#, ну и проинициализированная. extern static MethodName(ref StructureName structure);
|
|
|
Записан
|
|
|
|
MOPO3
Ай да дэдушка! Вах...
Команда клуба
Offline
Пол:
Холадна аднака!
|
|
« Ответ #26 : 15-02-2007 19:38 » |
|
Мороз, давн тебя не видно было, хорошо, что зашел. Можешь подсказать русскоязычную литературу, где бы расписывались подробно все (или большинство) тонкостей dllImport? Я пока читал только Троэлсена и местами Шилдта.
Сорри, но сейчас сходу не скажу , да и навряд ли знаю такую литературу на великом и могучем, потому как сам предпочитаю на ущербном англицком В понедельник буду на работе, гляну у себя в доках, авось и найду чего.
|
|
|
Записан
|
MCP, MCAD, MCTS:Win, MCTS:Web
|
|
|
Dimka
Деятель
Команда клуба
Offline
Пол:
|
|
« Ответ #27 : 15-02-2007 20:05 » |
|
В сигнатуре метода тип аргумента объявляется не как IntPtr, а как структура, описанная на C#, ну и проинициализированная.
extern static MethodName(ref StructureName structure); Не пойдёт. Нетипизированный указатель "void *" как раз там используется, где заранее не определён точный тип передаваемой структуры. Допустим, есть функция типа: void process(int *result_type, void **result); Где структура result зависит от значения result_type. Как получить result в C# - т.е. динамически проинтерпретировать нетипизированный указатель?
|
|
|
Записан
|
Программировать - значит понимать (К. Нюгард) Невывернутое лучше, чем вправленное (М. Аврелий) Многие готовы скорее умереть, чем подумать (Б. Рассел)
|
|
|
vins
Гость
|
|
« Ответ #28 : 16-02-2007 07:32 » |
|
Где структура result зависит от значения result_type. Как получить result в C# - т.е. динамически проинтерпретировать нетипизированный указатель? [DllImport("precess_dll.dll", EntryPoint="process")] extern static void process(ref int res_type, ref IntPtr result);
...
int res_type = 0; IntPtr ptr = IntPtr.Zero; process(ref res_type, ref ptr); Struct str = (Struct)Marshal.PtrToStructure(ptr, typeof(Struct));
|
|
|
Записан
|
|
|
|
Dimka
Деятель
Команда клуба
Offline
Пол:
|
|
« Ответ #29 : 16-02-2007 08:36 » |
|
Вот это и хотелось увидеть. Спасибо.
|
|
|
Записан
|
Программировать - значит понимать (К. Нюгард) Невывернутое лучше, чем вправленное (М. Аврелий) Многие готовы скорее умереть, чем подумать (Б. Рассел)
|
|
|
|