Страница 1 из 2

Вернуть структуру из сишной dll

Добавлено: 02 Декабрь 2021, 9:18
finsoftrz
Добрый день. Смотрю одну библиотеку на си. У нее некоторые функции возвращают структуру данных. Может, кто сталкивался, как описать прототип на кларионе?
Более конкретно.
Структура определена так.

Код: Выделить всё

typedef struct tagMData {
	int errCode;
	char data[256];
	int dataLength;
}MData;
Прототип вызова функции.

Код: Выделить всё

IMPORTDLL MData PIRITLIB_CALL libGetCountersAndRegisters(unsigned char numRequest);
В кларионе пробовал по разному, падает при вызове.

Код: Выделить всё

pirit_libGetCountersAndRegisters(BYTE),????,RAW,PASCAL,PROC,DLL(_libGetCountersAndRegisters_),name('libGetCountersAndRegisters')
Передача параметров PASCAL, с вызовами других функций проблем нет.

Вернуть структуру из сишной dll

Добавлено: 02 Декабрь 2021, 9:48
Admin
Типа так но про STRING не уверен... может CSTRING

Код: Выделить всё

MData       GROUP
errCode       LONG
data          STRING(256)
dataLength    LONG
            END

get_group   &MData

  CODE
  get_group &= pirit_libGetCountersAndRegisters(???)

Вернуть структуру из сишной dll

Добавлено: 02 Декабрь 2021, 9:49
Admin
pirit_libGetCountersAndRegisters должна возвращать LONG. Адрес структуры

Вернуть структуру из сишной dll

Добавлено: 02 Декабрь 2021, 9:55
Admin
СИ вроде как то так описываются

Код: Выделить всё

   MODULE('pilot_nt.dll')
     TSB_TestPinpad(),LONG,RAW,C,DLL(_TSB_TestPinpad_)
     TSB_card_authorize7(LONG track2, LONG auth_answer7_addr),LONG,RAW,C,DLL(_TSB_card_authorize7_)
     TSB_close_day(LONG auth_answer_addr),LONG,RAW,C,DLL(_TSB_close_day_)
   END

Вернуть структуру из сишной dll

Добавлено: 02 Декабрь 2021, 10:01
finsoftrz
В том то и дело, что не возвращает, падает при вызове. В том числе и при такой декларации.

Код: Выделить всё

pirit_libGetCountersAndRegisters(BYTE),LONG,RAW,PASCAL,PROC,DLL(_libGetCountersAndRegisters_),name('libGetCountersAndRegisters')

Вернуть структуру из сишной dll

Добавлено: 02 Декабрь 2021, 10:06
Admin
Я как то на такое попадал. Как то хитро решалось типа выключить (или включить) режим отладки Clarion DLL :)
Но по итогу потом переписал на динамическую загрузку и все решилось.
Вот ниже динамическая загрузка сберовской pilot_nt.dll для проверки подключения и вызова диалога оплаты

Вернуть структуру из сишной dll

Добавлено: 02 Декабрь 2021, 10:10
finsoftrz
Вот так работают все функции, кроме pirit_libGetStatusFlags и pirit_libGetCountersAndRegisters, которые должны возвращать структуру mdata. При их вызове приложение падает.

Код: Выделить всё

     MODULE('piritlib.dll')
       pirit_openPort(*cstring port, LONG speed),LONG,RAW,PASCAL,PROC,DLL(_openPort_),name('openPort')
       pirit_closePort(),LONG,RAW,PASCAL,PROC,DLL(_closePort_),name('closePort')
       pirit_checkPortAsync(*cstring port, LONG speed),LONG,RAW,PASCAL,PROC,DLL(_checkPortAsync_),name('checkPortAsync')
       pirit_commandStart(),LONG,RAW,PASCAL,PROC,DLL(_commandStart_),name('commandStart')
       pirit_libGetStatusFlags(),LONG,RAW,PASCAL,PROC,DLL(_libGetStatusFlags_),name('libGetStatusFlags')
       pirit_getStatusFlags(*LONG, *LONG, *LONG),LONG,RAW,PASCAL,PROC,DLL(_getStatusFlags_),name('getStatusFlags')
       pirit_getKKTInfo(BYTE, *CSTRING),LONG,RAW,PASCAL,PROC,DLL(_getKKTInfo_),name('getKKTInfo')
       pirit_libGetCountersAndRegisters(BYTE),LONG,RAW,PASCAL,PROC,DLL(_libGetCountersAndRegisters_),name('libGetCountersAndRegisters')
       pirit_scrollPaper(),LONG,RAW,PASCAL,PROC,DLL(_scrollPaper_),name('scrollPaper')
       pirit_libCutDocument(),LONG,RAW,PASCAL,PROC,DLL(_libCutDocument_),name('libCutDocument')
       pirit_libOpenDocument(BYTE, BYTE, *CSTRING, LONG ),LONG,RAW,PASCAL,PROC,DLL(_libOpenDocument_),name('libOpenDocument')
       pirit_libCancelDocument(),LONG,RAW,PASCAL,PROC,DLL(_libCancelDocument_),name('libCancelDocument')
       pirit_libPrintString(*CSTRING str, BYTE attr),LONG,RAW,PASCAL,PROC,DLL(_libPrintString_),name('libPrintString')
     END

Вернуть структуру из сишной dll

Добавлено: 02 Декабрь 2021, 10:23
Admin
Т.е. дело вообще не в возвращаемых параметрах если падает с ,PROC

Вернуть структуру из сишной dll

Добавлено: 02 Декабрь 2021, 10:24
finsoftrz
Я тоже через динамическую загрузку делаю, как в классе для atol, по аналогии.
Падает и с proc, и без...

Вернуть структуру из сишной dll

Добавлено: 02 Декабрь 2021, 10:29
finsoftrz
pirit_libGetStatusFlags() падает, а pirit_getStatusFlags, который считывает ту же информацию, но не через структуру, а по адресам в параметрах, отрабатывает корректно.

Вернуть структуру из сишной dll

Добавлено: 02 Декабрь 2021, 11:47
Игорь Столяров
finsoftrz писал(а): 02 Декабрь 2021, 10:29 pirit_libGetStatusFlags() падает
Покажите пожалуйста сишный прототип функции.
Вы начали с одной функции, перескочили на другую ... :(

Вообще возвращаемое значение никак не влияет на успешность вызова в Clarion.
Можете вообще ничего не получать (с "PROC").
Если вызов метода падает - проблема в описании входных параметров и самого метода.

Вернуть структуру из сишной dll

Добавлено: 02 Декабрь 2021, 12:09
finsoftrz
Да тоже самое все.

Код: Выделить всё

IMPORTDLL MData PIRITLIB_CALL libGetStatusFlags();

Вернуть структуру из сишной dll

Добавлено: 02 Декабрь 2021, 12:12
finsoftrz
Часть функций в библиотеки продублированы в более удобоваримый вид с передачей параметра с адресом для результата. Но не все из нужных...
Например, вышеприведенная.

Код: Выделить всё

IMPORTDLL int PIRITLIB_CALL getStatusFlags(int *fatalStatus, int *currentFlagsStatus, int *documentStatus);
Такая конструкция вызывается без проблем.

Вернуть структуру из сишной dll

Добавлено: 02 Декабрь 2021, 12:15
finsoftrz
У меня пока подозрение, что при mdata надо что-то в параметрах передавать. Я погуглил еще, в интернете тоже есть обсуждения проблемы (не для клариона). Но решения пока не увидел.

Вернуть структуру из сишной dll

Добавлено: 02 Декабрь 2021, 12:38
Игорь Столяров
finsoftrz писал(а): 02 Декабрь 2021, 12:15 что при mdata надо что-то в параметрах передавать
Вряд ли. :( Вариант вызова без получения результата падает ?
Без динамической загрузки, с обычной линковкой DLL.

Код: Выделить всё

  pirit_libGetStatusFlags()