首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >DevC++ C调用OpenCobolIDE模块

DevC++ C调用OpenCobolIDE模块
EN

Stack Overflow用户
提问于 2017-08-28 00:23:15
回答 1查看 433关注 0票数 1

我正在尝试使用开发人员C++集成开发环境从一个用C编写的程序中调用一个OpenCobol文件处理例程(它们是免费的,我喜欢它们)。

当您将代码编译为模块时,Cobol环境会生成一个DLL,所以我希望我可以只使用调用代码的普通方法(见下文)。如果按照下面的方式编译和运行,我会得到错误消息"libcob: cob_init()尚未被调用“,然而,在相关位置包含头文件和库并取消代码中的部分注释后,我得到了一条”未定义的对_imp_cob_init的引用“消息。

我显然遗漏了一些简单的东西。任何帮助都将不胜感激。

AdyB

代码语言:javascript
复制
#include <stdio.h>
#include <stdlib.h>
#include <stddef.h>
#include <string.h>
#include <windows.h>

/*
#ifdef __cplusplus
extern "C" {
#endif
#include "libcob.h"

#ifdef __cplusplus
}
#endif
*/

typedef void (*pFile)(char*);

pFile filehandler=NULL;
char dllpath[256];

int main(int argc, char *argv[])
{
    HINSTANCE hLib;
    char txt[100]="this is a test";

/*  cob_init(0, NULL);*/

    hLib = LoadLibrary("F:\\source\\filehandler\\bin\\filehandler.dll");
    if (!hLib)
    {
      perror("Error loading dll");
      exit(1);
    }

    GetModuleFileName((HMODULE)hLib, (LPTSTR)dllpath, sizeof(dllpath));
    printf("Opened %s\n\n", dllpath);

    filehandler = (pFile)GetProcAddress((HMODULE)hLib, "filehandler");
    if (!filehandler)
    {
      perror("Can't find dll function");
      exit(1);
    }

    filehandler(txt);

    return 0;
}
EN

回答 1

Stack Overflow用户

发布于 2017-08-28 20:05:35

您已经混合了这两个调用,现在部分使用了COBOL运行时库libcob,部分不使用它。通常,您可以执行以下操作之一(大多数情况下是第三个选项):

  1. 只需将生成的COBOL dll用作“普通”dll,而不关心任何清理工作。使用"clean“runtime initialization

cleanup

  1. 选项,并将COBOL模块的加载留给libcob

完成。

选项1:“最简单的解决方案”-使用COBOL模块,无需清理

删除C源代码中libcob的注释。

cobc -fimplicit-init filehandler.cob编译你的COBOL模块,这样初始化就会自动完成。

注意:这会导致模块加载的额外启动时间最短(具体多少取决于所使用的libcob版本,但一般不会太多)。

可能的问题:您没有清理COBOL部分的选项,在您完成(甚至关闭)模块句柄后,它们仍将处于活动状态。

选项2:“更干净的解决方案,但仍然涉及模块加载的系统特定部分”

在没有-fimplicit-init的情况下编译COBOL模块,并将代码更改为

代码语言:javascript
复制
#include <stdio.h>
#include <stdlib.h>
#include <stddef.h>
#include <string.h>
#include <windows.h>

#ifdef __cplusplus
extern "C" {
#endif
#include "libcob.h"

#ifdef __cplusplus
}
#endif

typedef void (*pFile)(char*);

pFile filehandler=NULL;
char dllpath[256];

int main(int argc, char *argv[])
{
    HINSTANCE hLib;
    char txt[100]="this is a test";

#if !defined PASS_COMMAND_LINE_TO_COBOL
    cob_init(0, NULL);     /* initialization of COBOL runtime, no command line passed */
#else
    cob_init(argc, argv);  /* initialization of COBOL runtime, complete command line passed */
#endif

    hLib = LoadLibrary("F:\\source\\filehandler\\bin\\filehandler.dll");
    if (!hLib)
    {
      perror("Error loading dll");
      exit(1);
    }

    GetModuleFileName((HMODULE)hLib, (LPTSTR)dllpath, sizeof(dllpath));
    printf("Opened %s\n\n", dllpath);

    filehandler = (pFile)GetProcAddress((HMODULE)hLib, "filehandler");
    if (!filehandler)
    {
      perror("Can't find dll function");
      exit(1);
    }

    filehandler(txt);

#if defined (cob_c8_ptr) /* hack for checking if you use a 2.x+ version, not *really* needed in this case */
    cob_tidy;  /* finalizing of COBOL runtime (OC/GC function) */
#else
    cobtidy;   /* finalizing of COBOL runtime (MF compatibility function name available since OpenCOBOL 1.1 released Feb 2009 [still available (as define) in 2.x+ version]) */
#endif

    return 0;
}

或者(如果您确实想在COBOL调用之后退出)将最后一个代码部分更改为:

代码语言:javascript
复制
    int cob_return_int = filehandler(txt);
    cob_stop_run (cob_return_int);

重要提示:您现在需要同时包含libcob.h,以便C编译器知道函数声明并链接到libcob库(最有可能的方法是将-lcob添加到DevC++中的编译器选项中,否则您将从C链接器获得“未定义的引用”消息)。

选项3:“干净的解决方案,把所有的COBOL都留给libcob”

显然,在这种情况下,您也必须链接到libcob。

代码语言:javascript
复制
#include <stdio.h>
#include <stdlib.h>
#include <stddef.h>
#include <string.h>

#ifdef __cplusplus
extern "C" {
#endif
#include "libcob.h"

#ifdef __cplusplus
}
#endif

int main(int argc, char *argv[])
{
    cob_call_union  filehandler_module;
    int     cob_return_int;
    char txt[100]="this is a test";

    /* initialization of COBOL runtime, complete command line passed */
    cob_init(argc, argv);

    /* search and load a function pointer for program-id "filehandler" in a module called "filehandler" */
    filehandler_module.funcvoid = cob_resolve ("filehandler");
    if (filehandler_module.funcvoid == NULL) {
        /* this will display the error and return with 1, as your old code did */
        cob_call_error ();
        /* if you just want the error text in a local buffer call `cob_resolve_error` instead */
    }

    /* calling the COBOL module "filehandler" and store its return-code in cob_return_int */
    cob_return_int = filehandler_module.funcint(txt);

    /* NOTE: you may call additional COBOL modules (or the same with a different option) here, maybe depending on `cob_return_int` */

    cob_tidy;  /* finalizing the COBOL runtime */

    /* NOTE: more code goes here, likely handling `cob_return_int` */

    return 0;
}

代码中唯一“缺失”的是"filehandler.dll“的路径。libcob首先尝试当前路径,所以如果您的模块在那里,就不需要调整它。

在应用程序外部通过set COB_LIBRARY_PATH=F:\source\filehandler\bin指定模块查找路径。

如果你真的想在你的应用程序中硬连接它,并且有一个最新的版本(读作“近乎最新的开发快照”),你可以通过调用cob_setenv("COB_LIBRARY_PATH", "F:\\source\\filehandler\\bin", 1);来实现-使用setenv()putenv()可以做到这一点(但这在很大程度上依赖于用于你的程序和libcob的C运行时库。

如果可能,我总是建议(对于GnuCOBOL的“当前”版本)使用runtime configuration file,并用set COB_RUNTIME_CONFIG=X:\PATH\TO\filehandler.cfg或上面概述的环境函数指定它的路径。

如果你使用的是比GnuCOBOL 2.2rc更早的版本,我总是建议你改用最新版本的GnuCOBOL,但这是另一个问题……

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/45906990

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档