gpt4 book ai didi

c - DevC++ C 调用 OpenCobolIDE 模块

转载 作者:太空宇宙 更新时间:2023-11-04 02:29:25 25 4
gpt4 key购买 nike

我正在尝试从使用 Dev C++ IDE(它们是免费的,我喜欢它们)用 C 编写的程序调用 OpenCobol 文件处理例程。

当您将代码编译为模块时,Cobol 环境会生成一个 DLL,因此我希望我可以使用调用代码的常规方法(见下文)。如果按如下方式编译和运行,我会收到错误消息“libcob: cob_init() has not been called”,但是,在相关位置包含 header 和库并取消注释代码中的部分后,我会得到一个“未定义的”引用 _imp_cob_init"消息。

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

阿迪B

#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;
}

最佳答案

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

  1. 仅将生成的 COBOL dll 用作“普通”dll,不关心任何清理

  2. 使用“干净”的运行时初始化和清理

  3. 使用选项并将 COBOL 模块的加载留给 libcob

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

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

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

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

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

选项 2:“更清洁的解决方案,但仍涉及用于模块加载的系统特定部分”

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

#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 调用后退出)将最后的代码部分更改为:

    int cob_return_int = filehandler(txt);
cob_stop_run (cob_return_int);

重要提示:您现在需要同时包含 libcob.h,以便 C 编译器了解函数声明到 libcob 库的链接(很可能通过添加 -lcob 到 DevC++ 中的编译器选项(否则您将从 C 链接器获得“ undefined reference ”消息)。

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

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

#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,但这是一个不同的问题...

关于c - DevC++ C 调用 OpenCobolIDE 模块,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45906990/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com