Вызовите функции Cobol или C в программе Cobol, вызываемой программой C # - PullRequest
0 голосов
/ 28 мая 2018

Я работаю над простым консольным приложением в C # 4.6.1.Я могу сделать программу cobol, используя Micro Focus .Моя цель - вызвать из консольного приложения программу cobol, у которой есть вызовы другой программы cobol.

Сегодня я могу с успехом вызывать методы cobol в файле cobol dll, используя DllImport или LoadLibrary .

В моем примере мой метод cobol с именем Hello , в файле dll hello.dll , печать "Hello: D" и таким же образом моя другая программа на cobol с именем Itsme , в файле dll itsme.dll , печать "Это я" .

Внутри программы Cobol мы можем вызвать другую программу с его именем.В моем примере я добавляю следующую строку в мою Hello программу:

CALL "ITSME"

В моем консольном приложении я загружаю оба файла dll (hello.dll и itsme.dll).Когда я вызываю мой метод Hello , он должен вывести "Hello, это я" .Но это не произойдет из-за:

Ошибка загрузки: файл 'Itsme'

код ошибки: 173, pc = 0, call = 1, seg = 0 173
Вызванный программный файл не найден в каталоге drive / 10 *

Я знаю, что он работает в системе Unix, используя dlopen вместо LoadLibrary . LoadLibrary не эквивалентен dlopen ?

РЕДАКТИРОВАТЬ: есть небольшой пример кода после просмотра ответа Саймона Собиша:

#include "stdafx.h"
#include "stdio.h"
#include "windows.h"
#include "cobtypes.h"

typedef int(__stdcall *f_cobinit)();
typedef cobrtncode_t(__stdcall *f_cobcall)(const cobchar_t *callname, int argcnt, cobchar_t **argvec);

int main()
{
    HINSTANCE dll1 = LoadLibrary("CobolDlls.dll");
    HINSTANCE dll2 = LoadLibrary("CobolDlls2.dll");
    HINSTANCE dllCbl = LoadLibrary("cblrtsm.dll");

    printf("cobinit : ");
    f_cobinit init = (f_cobinit)GetProcAddress(dllCbl, "cobinit");
    printf("%d", init());

    f_cobcall hi = (f_cobcall)GetProcAddress(dllCbl, "cobcall");
    cobrtncode_t c = hi((cobchar_t*)"P2", 0, NULL);

    getchar();
}

Я успешно загрузил библиотеки, и мой вызов cobinit работает (результат: 0).Но когда я вызываю метод cobcall , у меня появляется код ошибки 173.

Я уточняю, что "P2" ссылается на программу cobol с именем "P2", включенную в "CobolDlls.dll".", который построен как общая библиотека с одной динамкой с MicroFocus, и все Dll находятся в одном каталоге с консольным приложением.

P2 программа:

   identification division.
   program-id. P2.
   data division.
   working-storage section.
   local-storage section.
   procedure division.
   display "Hello I'm P2"
   goback.

Спасибо за вашу помощь,Йоанн

1 Ответ

0 голосов
/ 28 мая 2018

Примечание: это догадка , поскольку я не проверял это, но для большинства реализаций COBOL есть библиотека времени выполнения (которая должна быть целью для dlopen / LoadLibrary), которая предоставляет функции

Быстрый поиск в документации Micro Focus показал C Функции для вызова COBOL , вы, вероятно, захотите использовать cobinit(), cobcall() и cobtidy().

Поскольку все, что касается частей COBOL, выполняется библиотекой времени выполнения (которая должна быть либо связана, либо загружена сама), вам необходимо установить параметры, например, где найти модули и другие, возможно, соответствующиенастройки до вызова cobinit().

Возможно, понадобится одна настройка: COBPATH - Если модули COBOL не находятся в текущем каталоге процесса * -установить так же, как и переменную PATH (записи, разделенные ";" в Windows)

В этом случае я бы попробовал что-то подобное (в C #, образец был C ++)

System.Environment.SetEnvironmentVariable("COBPATH", "X:\path;Y:\other-path");

Согласно документамИнформация о Вызов программ комбинированные программы загружаются путем загрузки библиотеки, содержащей их, сначала простым CALL.Ваша настроенная программа будет выглядеть следующим образом:

#include "stdafx.h"
#include "stdio.h"
#include "windows.h"
#include "cobtypes.h"

typedef int(__stdcall *f_cobinit)();
typedef cobrtncode_t(__stdcall *f_cobcall)(const cobchar_t *callname, int argcnt, cobchar_t **argvec);

int main()
{
    HINSTANCE dllCbl = NULL;

    f_cobinit cobInit = NULL;
    f_cobcall cobCall = NULL;

    int retCode;

    printf("load COBOL runtime : ");
    HINSTANCE dllCbl = LoadLibrary("cblrtsm.dll");
    if (!dllCbl) {
        retCode = (int)GetLastError();
        printf("failure: %d\n", retCode);
        return retCode;
    }
    puts("success");

    printf("lookup COBOL functions : ");
    cobInit = (f_cobinit)GetProcAddress(dllCbl, "cobinit");
    cobCall = (f_cobcall)GetProcAddress(dllCbl, "cobcall");
    printf("init: %p, call: %p - ", (void *)cobInit, (void *)cobCall);
    if (!cobInit || !cobCall) {
        retCode = (int)GetLastError();
        printf("failure: %d\n", retCode);
        return retCode;
    }
    puts("success");


    printf("cobinit : ");
    retCode = cobInit();
    if (retCode) {
        printf("failure: %d\n", retCode);
        return retCode;
    }
    puts("success");

    printf("preload CobolDlls : ");
    retCode = cobCall((cobchar_t*)"CobolDlls", 0, NULL);
    puts("success");

    //printf("preload CobolDlls2 : ");
    //retCode = cobCall((cobchar_t*)"CobolDlls2", 0, NULL);
    //puts("success");

    printf("do actual CALL "P2" : ");
    retCode = cobCall((cobchar_t*)"P2", 0, NULL);
    printf("returned with: %d\n", retCode);

    getchar();
}

Примечание. Помните, что среда выполнения COBOL может выдавать exit (особенно, если в деталях COBOL имеются ошибки или модуль STOP RUN).Вы хотите быть в состоянии поймать его.

...