#c #cobol #gnucobol
#c #cobol #gnucobol
Вопрос:
Я изучаю COBOL просто ради удовольствия и теперь хочу вызывать функции C из моего исходного кода COBOL (используя GnuCOBOL).
Я могу вызывать функции C просто отлично, однако у меня небольшая проблема с моей функцией, которая выглядит следующим образом: (на данный момент она просто оборачивает другую функцию с теми же аргументами)
int getSensors( char * protocol, int protocolLen,
char * model, int modelLen,
int * id, int * dataTypes ) {
return tdSensor(protocol, protocolLen, model, modelLen, id, dataTypes );
}
Моя проблема в том, что значение, возвращаемое в переменной id, не может быть напечатано позже в COBOL (TSI-ID ниже). Например, возвращаемое значение может быть 67, и если я напечатаю переменную в COBOL, я получу символ ascii ‘C’ вместо ожидаемого значения 0067.
Запись COBOL выглядит следующим образом:
01 TELLSTICK-SENSOR-ITER.
05 TSI-PROTOCOL PIC X(50).
05 TSI-MODEL PIC X(50).
05 TSI-ID PIC 9(4).
05 TSI-DATATYPES PIC 9(4).
05 TSI-RETURN PIC S9(4).
И мой вызов выглядит следующим образом:
CALL "getSensors" USING
BY REFERENCE TSI-PROTOCOL BY VALUE 50
BY REFERENCE TSI-MODEL BY VALUE 50
BY REFERENCE TSI-ID
BY REFERENCE TSI-DATATYPES
RETURNING TSI-RETURN.
Я новичок в COBOL, и мои навыки C довольно подзабыты, поскольку я обычно работаю на Java. Есть ли очевидная ошибка новичка в моем коде здесь?
Комментарии:
1. UV для «cobol» и «just for fun» в одном предложении 🙂 и, что более серьезно, также для межъязыкового взаимодействия, которое является сложным.
2. Проверьте представление памяти для рисунка 9 (4). Прошло более 25 лет с тех пор, как я работал с COBOL, но IIRC PIC 9 (4) не сохраняется как int. Следовательно, вы не можете присваивать значения целому числу в C и ожидать, что оно будет нормально выглядеть в COBOL. Может быть, преобразовать C-int в не ограниченную 4-байтовую строку ASCII-цифр?
3. Вы получаете ровно X ’67’, который является ASCII для ‘C’? Нет начальных или завершающих пробелов или чего-либо еще? По сути, вы должны описать свои данные в программе COBOL точно так же, как их определяет программа C. Та же длина, тот же тип. Посмотрите в руководстве пользователя GnuCOBOL Гэри Катлера для версии V2 (вы должны использовать версию V2, если у вас ее еще нет), какие способы использования доступны.
4. Спасибо, ребята, ваш вклад подтолкнул меня в правильном направлении!
5. УФ, отсюда хороший вопрос , знакомящий нас с встроенным COBOL , языком будущего
INTERNET OF THINGS DIVISION
.
Ответ №1:
Если вы возвращаете int
, вы можете напрямую проверить RETURN-CODE
переменную и вообще не нужно использовать RETURNING
предложение.
Если вы хотите его использовать: int
сопоставляется с retvar USAGE BINARY-LONG
.
Комментарии:
1. Изменение рисунка 9 (4) на ДВОИЧНЫЙ-ЛОНГ решил проблему. Поскольку похоже, что функция tdSensor никогда не возвращает ничего большего, чем 255, я переключился на ДВОИЧНЫЙ символ БЕЗ ЗНАКА. Спасибо!
Ответ №2:
Пара разъяснений по другим комментариям и ответам.
Как уже говорилось, вы смешиваете COBOL USAGE DISPLAY
с USAGE BINARY
полями данных.
Попробуйте
01 TELLSTICK-SENSOR-ITER.
05 TSI-PROTOCOL PIC X(50).
05 TSI-MODEL PIC X(50).
05 TSI-ID USAGE BINARY-LONG.
05 TSI-DATATYPES USAGE BINARY-LONG.
05 TSI-RETURN USAGE BINARY-LONG.
и чтобы избежать небольшого дублирования магической нумерации, измените CALL
на
CALL "getSensors" USING
BY REFERENCE TSI-PROTOCOL BY VALUE LENGTH OF TSI-PROTOCOL
BY REFERENCE TSI-MODEL BY VALUE LENGTH OF TSI-MODEL
BY REFERENCE TSI-ID
BY REFERENCE TSI-DATATYPES
RETURNING TSI-RETURN
Я также удалил завершающий период в инструкции call, просто потому, что; если вы когда-нибудь переместите этот код внутрь IF
блока, вам не придется беспокоиться о завершении полной остановки. Используйте, END-CALL
если хотите, но это действительно необходимо, только если у вас есть ON EXCEPTION
блок условного кода, которому требуется завершение области видимости.
Комментарии:
1. Спасибо! Я многому научился из этих ответов и комментариев! 🙂
2. @Deps, тогда тебе, вероятно, понравится, open-cobol.sourceforge.net/faq/index.html
Ответ №3:
Просто случайная мысль, но попробуйте использовать comp 5 для поля int. Я не уверен в точном синтаксисе, но он похож на этот:
TSI-ID 9999 comp 5.
Comp 5 является двоичным представлением (попробуйте поиск в Google для получения более подробной информации)
Комментарии:
1. Да, но я полагаю, что это comp-5, иначе компилятор считает, что 5 — это число, а значение ключевого слова отсутствует.