Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: импорт библиотеки VC++ 6.0 в С# c помощью DllImport  (Прочитано 32812 раз)
0 Пользователей и 1 Гость смотрят эту тему.
Roof
Гость
« : 13-02-2007 16:58 » 

Еще вопрос как быть, если функция в Dll имеет такой вид:

err = GetAmplifyADC(typeDevice, numberDSP, 0, &amplifyADC0);

на С++ переменная amplifyADC0 обявлена как double

я так понимаю, что функции надо передать адрес этой переменной т.к стоит &

как это сделать на С#?
Записан
nikedeforest
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #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
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #3 : 13-02-2007 17:33 » 

Ааа, извини, я тебя не так понял. То что я написал про утилиту, это я не к месту.
Да, попробуй так, должно получиться.
Записан

ещё один вопрос ...
Roof
Гость
« Ответ #4 : 13-02-2007 17:46 » 

вроде получилось, тогда следующий вопросик, если тебя не затруднит, как быть
если функция требует в качестве параметра указатель?
Записан
nikedeforest
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #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
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #7 : 13-02-2007 18:27 » 

А что именно не ясно. Тебя смущает приведение типов? Или тебя смущает именно то, что функция возвращает указатель?
Записан

ещё один вопрос ...
Roof
Гость
« Ответ #8 : 13-02-2007 18:38 » 

Просто, как я понимаю, в памяти организуется буфер, куда АЦП складывает дискретные отсчеты, в С++ это делается через указатель, который является одним
из параметров функции, а вот как этот буфер реализовать на C#?
Возможно ли сделать массив типа float и попытаться его запихнуть в функцию?
Записан
nikedeforest
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #9 : 13-02-2007 18:42 » 

Я сейчас напишу кое что, если ты это знаешь, то извини, не хотел обидеть.
Дело в том, что тип short 16 бит в себе содержит, а тип byte 8 бит
В структуре выделяется массив типа byte из двух элементов. Каждый элемент по 8 бит.
А вот теперь смотри.
Вот  эта операция  pBuffer16ADC = (short*) pBuffer; присваивает указателю на тип short ( переменная pBuffer16ADC ) адрес первого элемента массива типа byte.
Надеюст ты понял. Если не понял, то объясню по -другому. А если знал, то извини.
Записан

ещё один вопрос ...
nikedeforest
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #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
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #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
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #14 : 13-02-2007 20:47 » 

Мда, хорошего по немножку Улыбаюсь. Не забыть завтра еще покапаться, самому интересно Улыбаюсь
Записан

ещё один вопрос ...
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline 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
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #17 : 14-02-2007 06:07 » 

Стоп, я что-то уже не понимаю. Это таже задача, что была до этого или уже другая?
Записан

ещё один вопрос ...
Roof
Гость
« Ответ #18 : 14-02-2007 06:10 » 

нет, движемся вперед, и это наверное последнее,что мне осталось решить
сейчас пробую что-нибудь с intPtr придумать
Записан
nikedeforest
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #19 : 14-02-2007 06:47 » 

А как ты ту задачу решил? Интересно же ...
Записан

ещё один вопрос ...
Roof
Гость
« Ответ #20 : 15-02-2007 03:16 » 

Честно говоря, я ее не решил, а перепоручил  Улыбаюсь по честному у меня нет на это времени
Смысл в слудующем, приобрел АЦП SigmaUSB16, а функции для работы с ним все в dll на VC++ 6.0
вот и пытаюсь их приспособить под C#... с перемеными успехами Здесь была моя ладья......
Записан
nikedeforest
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #21 : 15-02-2007 10:14 » 

Короче, предыдущая задача решается все таки тем, что ты pBuffer должен сделать массивом типа byte (такой тип в .НЕТ есть). Вот.
По поводу последней пока еще не думал.
Записан

ещё один вопрос ...
MOPO3
Ай да дэдушка! Вах...
Команда клуба

lt
Offline Offline
Пол: Мужской
Холадна аднака!


WWW
« Ответ #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
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #23 : 15-02-2007 16:39 » 

Мороз, давн тебя не видно было, хорошо, что зашел. Можешь подсказать русскоязычную литературу, где бы расписывались подробно все (или большинство) тонкостей dllImport? Я пока читал только Троэлсена и местами Шилдта.
Записан

ещё один вопрос ...
Dimka
Деятель
Команда клуба

ru
Offline 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
Ай да дэдушка! Вах...
Команда клуба

lt
Offline Offline
Пол: Мужской
Холадна аднака!


WWW
« Ответ #26 : 15-02-2007 19:38 » 

Мороз, давн тебя не видно было, хорошо, что зашел. Можешь подсказать русскоязычную литературу, где бы расписывались подробно все (или большинство) тонкостей dllImport? Я пока читал только Троэлсена и местами Шилдта.
Сорри, но сейчас сходу не скажу , да и навряд ли знаю такую литературу на великом и могучем, потому как сам предпочитаю на ущербном англицком Улыбаюсь В понедельник буду на работе, гляну у себя в доках, авось и найду чего.
Записан

MCP, MCAD, MCTS:Win, MCTS:Web
Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #27 : 15-02-2007 20:05 » 

Цитата: vins
В сигнатуре метода тип аргумента объявляется не как IntPtr, а как структура, описанная на C#, ну и проинициализированная.

extern static MethodName(ref StructureName structure);
Не пойдёт. Нетипизированный указатель "void *" как раз там используется, где заранее не определён точный тип передаваемой структуры.

Допустим, есть функция типа:
Код: (C)
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
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #29 : 16-02-2007 08:36 » new

Вот это и хотелось увидеть. Спасибо.
Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines