:: Visual Foxpro, Foxpro for DOS
Преобразование кода из C в VFP9
Victoriacom
Автор

Сообщений: 111
Дата регистрации: 08.12.2010
Здравствуйте, форумчане!
Проблема такая. Мне надо организовать связь с китайским прибором Anviz FacePass 7. Обратился к разработчикам за SDK. Дали. Но SDK написан для языка C.
Я уже решал подобные задачи для других их приборов. Там все получалось. А тут... Я уже написал им, но ответа от них не дождешься.
Такая затырка. Используется их библиотека tc-b_new_sdk.dll
Код на С из SDK выглядит так:

CChex_Init(); - инициализация интерфейса
IntPtr sdk_handle = CChex_Start(); - старт SDK, распределение памяти и организация связи с прибором. Возвращает хэндл.
int CChex_GetNetConfig(IntPtr CchexHandle, int DevIdx); - запрос сетевой конфигурации

На фоксе я изобразил так:
DECLARE CChex_Init IN tc-b_new_sdk.dll
DECLARE INTEGER CChex_Start IN tc-b_new_sdk.dll
DECLARE INTEGER CChex_GetNetConfig IN tc-b_new_sdk.dll INTEGER @, INTEGER

=CChex_Init()
nHandle = CChex_Start()
nDeviceId = 1
nRet = CChex_GetNetConfig(@nHandle,nDeviceId)

Инициализация и старт проходят нормально. Все функции без параметров отрабатывают.
А вот с параметрами, как в последней строчке, выдает ошибку:
Declare DLL call caused an exception
без комментариев. Засовывал ее в TRY, - тоже самое - без комментариев.
Проблема в том, что на С я никогда не писал.



Исправлено 1 раз(а). Последнее : Victoriacom, 18.10.18 12:48
Ratings: 0 negative/0 positive
Re: Преобразование кода из C в VFP9
Pliskin

Сообщений: 2959
Откуда: Новосибирск
Дата регистрации: 19.11.2003
По-моему надо так
DECLARE INTEGER CChex_GetNetConfig IN tc-b_new_sdk.dll INTEGER, INTEGER
nRet = CChex_GetNetConfig(nHandle,nDeviceId)
Ratings: 0 negative/0 positive
Re: Преобразование кода из C в VFP9
Victoriacom
Автор

Сообщений: 111
Дата регистрации: 08.12.2010
Спасибо, ошибка пропала. Только функция не работает.
Мне казалось, что если в параметрах - указатель, значит нужно ставить символ @.
Ладно, буду разбираться в SDK дальше. Текст мягко говоря без подробностей...
Ratings: 0 negative/0 positive
Re: Преобразование кода из C в VFP9
Igor Korolyov

Сообщений: 34580
Дата регистрации: 28.05.2002
Указатель, это если бы на какую структуру, да ты её ещё и сам делал, память под неё выделял. А у тебя тупо адрес возвращает - это просто число. Ты же патаешься передать указатель на это самое число - а этого не нужно.


------------------
WBR, Igor
Ratings: 0 negative/0 positive
Re: Преобразование кода из C в VFP9
of63

Сообщений: 25254
Откуда: Н.Новгород
Дата регистрации: 13.02.2008
Может что-то похожее на функции, которые сами занимают память, и потом эту память надо не забыть освобождать.

Например функция в NETAPI32:
* DECLARE NetRemoteTOD ... STRING, INTEGER @ && функция, сама занимающая память
* DECLARE NetApiBufferFree ... INTEGER && освобождалка этой памяти (может просто типа LocalFree)
m.t = 0 && сюда будет записан АДРЕС памяти с структурой дата/время, не забыть потом ее освободить!
=NetRemoteTOD(имя_сервера, @t) && Время на удаленном сервере, по Гривинчу (UTC==GMT). Выделяет память, адрес ее кладет в T
* читаем структуру в блоке памяти с адресом T
=NetApiBufferFree(m.t) && освобождаем занятую память
Ratings: 0 negative/0 positive
Re: Преобразование кода из C в VFP9
Igor Korolyov

Сообщений: 34580
Дата регистрации: 28.05.2002
Ну если там есть Init да Start, то вероятно есть и какие то Stop да Terminate/Close. Только это явно не будет относится к вопросу основной работы с функциями - это будет нужно чтобы прога нормально завершала свою работу...


------------------
WBR, Igor
Ratings: 0 negative/0 positive
Re: Преобразование кода из C в VFP9
of63

Сообщений: 25254
Откуда: Н.Новгород
Дата регистрации: 13.02.2008
Я к тому, что возможно функция ..._Start()
IntPtr sdk_handle = CChex_Start()
возвращает адрес занятой памяти, далее эту память разбираешь согласно описанию (или передаешь процедурам из SDK)
и потом ее освобождаешь (надо читать описание, есть ли функция "конец работы". Если есть, то значит механика может быть такой, как с NetRemoteTOD). Если что, то работа с памятью в фоксе есть - SYS(2600)

Игорь, я понял, что ты так и написал, что надо передавать число...
DECLARE INTEGER CChex_GetNetConfig IN tc-b_new_sdk.dll INTEGER @, INTEGER
nRet = CChex_GetNetConfig(@nHandle,nDeviceId) - здесь @ уже не влияет



Исправлено 2 раз(а). Последнее : of63, 20.10.18 17:08
Ratings: 0 negative/0 positive
Re: Преобразование кода из C в VFP9
Victoriacom
Автор

Сообщений: 111
Дата регистрации: 08.12.2010
Нет, IntPtr sdk_handle = CChex_Start() возвращает просто дескриптор.
Проглядел весь SDK быстрым глазом, - большинство функций работают в паре с некоей "CChex_Update".

nRet = CChex_Update(nHandle, nDevIdx, @nType, nAddr, nLen) && nDevIdx, просто =1, как написали китайцы
В nType заносится числовой тип запроса, в зависимости от вызываемой перед этим функцией. А nAddr и nLen, собственно распределяемая память.
В документации я не нашел, как выделяется эта память, поэтому использую то, что нагуглил:

hHeap = GetProcessHeap()
nAddr = HeapAlloc(hHeap,1,nLen) && В nLen заношу размер структуры
cBuffer = SYS(2600,nAddr,nLen,REPLICATE(CHR(0), nLen)) && чищу буфер перед вызовом CChex_Update

Китайцы неохотно делятся своими секретами. На пять моих писем ответили двумя.
Буду брать их измором.



Исправлено 1 раз(а). Последнее : Victoriacom, 22.10.18 18:23
Ratings: 0 negative/0 positive
Re: Преобразование кода из C в VFP9
of63

Сообщений: 25254
Откуда: Н.Новгород
Дата регистрации: 13.02.2008
"В паре" - это как? Покажи последовательность вызовов какого-нибудь обращения к прибору.
Кстати, "дескриптор" конечно число, но за ним может стоять созданная в памяти структура. Например, этот "...Alloc" тоже возвращает число...



Исправлено 1 раз(а). Последнее : of63, 22.10.18 19:36
Ratings: 0 negative/0 positive
Re: Преобразование кода из C в VFP9
Igor Korolyov

Сообщений: 34580
Дата регистрации: 28.05.2002
Victoriacom
А nAddr и nLen, собственно распределяемая память.
В документации я не нашел, как выделяется эта память, поэтому использую то, что нагуглил:

hHeap = GetProcessHeap()
nAddr = HeapAlloc(hHeap,1,nLen) && В nLen заношу размер структуры
cBuffer = SYS(2600,nAddr,nLen,REPLICATE(CHR(0), nLen)) && чищу буфер перед вызовом CChex_Update
Вполне возможно что достаточно будет тривиального
lcBuffer = SPACE(m.lnLen) && Да хоть бы и REPLICATE(0h00, m.lnLen)
* обычно не суть важно начальное заполнение буфера, если он должен быть "неинициализирован"
* в декларации АПИшки объявить параметры как STRING @, INTEGER и вызывать как
... @lcBuffer, m.lnLen ...

Доверив всё управление памятью собственно фоксу. Конечно, если буфер не "долгоиграющий" - т.е. не должен один и тот же (по адресам) в целой последовательности вызовов методов быть - это, конечно, отвратительный дизайн, но от китайцев можно чего угодно ждать...


------------------
WBR, Igor




Исправлено 1 раз(а). Последнее : Igor Korolyov, 22.10.18 22:15
Ratings: 0 negative/0 positive
Re: Преобразование кода из C в VFP9
Igor Korolyov

Сообщений: 34580
Дата регистрации: 28.05.2002
of63
Кстати, "дескриптор" конечно число, но за ним может стоять созданная в памяти структура. Например, этот "...Alloc" тоже возвращает число...
Обычно когда говорят про дескриптор/хэндл, то подразумевают что НЕЛЬЗЯ его трактовать как адрес соответствующей структуры "где то внутрях" - т.е. нельзя лезть в эту память напрямую - только через соответствующие АПИ функции. Вот если бы речь шла про указатель - тогда другое дело Но АПИ стараются так не делать - слишком много шансов что прикладной разработчик "накосячит", да и менять "внутренности" в таком случае нельзя из-за разрушения совместимости с ранее написаным софтом. Тогда как "дескриптор" и набор функций для доступа к разным "полям" соответствующей внутренней структуры - решают большинство проблем и существенно повышают надёжность системы.


------------------
WBR, Igor
Ratings: 0 negative/0 positive
Re: Преобразование кода из C в VFP9
of63

Сообщений: 25254
Откуда: Н.Новгород
Дата регистрации: 13.02.2008
> Но АПИ стараются так не делать - слишком много шансов что прикладной разработчик "накосячит"
да, есть шанс накосячить (не по чистить эту память например, после ее анализа. Пример я привел). Всяко может быть, тем более в Китае или Индии. И даже пример с шансом на полное занятием памяти от MS существует ...

На месте МС я бы прятал эти внутренние АПИ-функции в фреймверк (и еще добавить нового, точка нет называется?), типа, в моем случае вызываем функцию NEW.xxxTOD (а уже она вызывает АПИшку, выделяющею память, читает результат, и вызывает закрывающую часть. Записывает считанное каким-то более "штатным образом" на новый вывод, т.е обертка старого го..на под новое. Это нормально, обернуть, даже без претензий. Потому-что и старое г.но еще кто-то пользует, и не только в РФии)



Исправлено 2 раз(а). Последнее : of63, 23.10.18 00:08
Ratings: 0 negative/0 positive
Re: Преобразование кода из C в VFP9
Victoriacom
Автор

Сообщений: 111
Дата регистрации: 08.12.2010
Вот, например, как описан вызов CChex_GetNetConfig с сохранением, так сказать, орфографии:
Function Query Anviz device’s network Configuration
Mode int CChex_GetNetConfig(IntPtr CchexHandle, int DevIdx);
Parameter CChex_Start successfully create the handle;Input[Parameter];
DevIdx,search the device Input[Parameter];

Return value 1;The command was executed successfully.;Minus;Execute command failure

Дальше описывается CChex_Update:
Actual Data CChex_Update, Type return CCHEX_RET_GETNETCFG_TYPE
Data Part
uint MachineId; // Device ID
int Result; // 0:OK, -1:error
byte [4]IpAddr;// IP address
byte [4]IpMask;// Mask
byte [6]MacAddr;// MAC
byte [4]GwAddr;// Gateway
byte [4]ServAddr;// Sever IP address
byte RemoteEnable;//Standby
byte [2]Port;// Port
byte Mode;// Mode 0: Server,1:Client
byte DhcpEnable;// DHCP 0isable; 1:Enable

Sample
int ret = CChex_GetNetConfig();

Notice
1.Make sure that CChex_Start has been started successfully before run.

Из чего я сделал вывод, что CChex_Update используется в паре.

Если посмотреть на синтаксис int CChex_Update(IntPtr CchexHandle, int[] DevIdx, int[] Type, IntPtr Buff, int Len), то видно, что IntPtr Buff - адрес памяти, int Len - длина памяти, где должна появиться вышеописанная структура.



Исправлено 3 раз(а). Последнее : Victoriacom, 23.10.18 16:12
Ratings: 0 negative/0 positive
Re: Преобразование кода из C в VFP9
lulgu

Сообщений: 1838
Дата регистрации: 30.11.2016
Если не ошибаюсь, один из законов Мерфи:
"Прочтите, наконец, эту чертову документацию!".
Ratings: 0 negative/0 positive
Re: Преобразование кода из C в VFP9
Victoriacom
Автор

Сообщений: 111
Дата регистрации: 08.12.2010
Да! И еще. "Если вы читаете эту инструкцию, значит у вас ничего не получилось." Это знакомо.

И еще вопрос.
Как работать с памятью?
Там просто указано, что в параметрах нужно указывать адрес буфера.
Я делаю один вызов в начале программы
hHeap = GetProcessHeap()

а потом перед каждым вызовом захватываю новую порцию из кучи
nAddr = HeapAlloc(hHeap,1,nLen)
отправляю в функцию адрес и длину, а после вызова функции (после анализа буфера) освобождаю
nRet = HeapFree(hHeap,0,nAddr)

А в конце программы
nRet = HeapDestroy(hHeap).

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



Исправлено 1 раз(а). Последнее : Victoriacom, 23.10.18 11:56
Ratings: 0 negative/0 positive
Re: Преобразование кода из C в VFP9
Simple777

Сообщений: 33855
Дата регистрации: 05.11.2006

RTFM

Ratings: 0 negative/0 positive
Re: Преобразование кода из C в VFP9
of63

Сообщений: 25254
Откуда: Н.Новгород
Дата регистрации: 13.02.2008
Можно новый памяти кусок заводить каждый раз, можно и старый использовать (если по размеру подходит), без разницы
Ratings: 0 negative/0 positive
Re: Преобразование кода из C в VFP9
Victoriacom
Автор

Сообщений: 111
Дата регистрации: 08.12.2010
Simple777

RTFM

СПС.
Документацию читаю. Но что толку, если с самого начала результат ноль! Мне бы хотя бы сдвинуть эту махину с места. Дальше уж сам. Но она, собака, не двигается.
Ratings: 0 negative/0 positive
Re: Преобразование кода из C в VFP9
Simple777

Сообщений: 33855
Дата регистрации: 05.11.2006
Мабуть, щэ нэ вмерла...
Ratings: 0 negative/0 positive
Re: Преобразование кода из C в VFP9
lulgu

Сообщений: 1838
Дата регистрации: 30.11.2016
Victoriacom
Да! И еще. "Если вы читаете эту инструкцию, значит у вас ничего не получилось." Это знакомо.

О чем и речь - не читать, а прочитать, это разные вещи.
У вас там полно разных функций - вы для них написали обертки?
Объектную модель для своего устройства разработали?
Использование класса PChart для работы с памятью вы рассматривали?
+
Не помешало бы проверить типы данных:
DECLARE INTEGER CChex_GetNetConfig IN tc-b_new_sdk.dll LONG, INTEGER



Исправлено 1 раз(а). Последнее : lulgu, 23.10.18 12:21
Ratings: 0 negative/0 positive


Извините, только зарегистрированные пользователи могут оставлять сообщения в этом форуме.

On-line: 22 (Гостей: 22)

© 2000-2024 Fox Club 
Яндекс.Метрика