GnuCOBOL 与 MySQL C API 接口问题(找不到调用的函数)

问题描述 投票:0回答:1
C:\gnuCobol>cobc -d -v -x -o mysql1 mysql1.cob -L"C:\Program Files\MySQL\MySQL Server 8.0\lib" -llibmysql
cobc (GnuCOBOL) 3.2.0
Built     Jul 28 2023 16:08:08  Packaged  Jul 28 2023 16:58:47 UTC
C version (MinGW) "13.1.0"
loading standard configuration file 'default.conf'
command line:   cobc -d -v -x -o mysql1 -LC:\Program Files\MySQL\MySQL Server 8.0\lib -llibmysql mysql1.cob 
preprocessing:  mysql1.cob -> C:\Users\Omistaja\AppData\Local\Temp\cob83652_0.cob
return status:  0
parsing:        C:\Users\Omistaja\AppData\Local\Temp\cob83652_0.cob (mysql1.cob)
return status:  0
translating:    C:\Users\Omistaja\AppData\Local\Temp\cob83652_0.cob -> C:\Users\Omistaja\AppData\Local\Temp\cob83652_0.c (mysql1.cob)
executing:      gcc -c -I"C:\gnuCobol\include" -o
                "C:\Users\Omistaja\AppData\Local\Temp\cob83652_0.o"
                "C:\Users\Omistaja\AppData\Local\Temp\cob83652_0.c"
return status:  0
executing:      gcc -Wl,--export-all-symbols -Wl,--enable-auto-import
                -Wl,--enable-auto-image-base -o "mysql1.exe"
                "C:\Users\Omistaja\AppData\Local\Temp\cob83652_0.o"
                -L"C:\gnuCobol\lib" -L"C:\Program Files\MySQL\MySQL Server
                8.0\lib" -L/mingw64/lib -lcob -l"libmysql"
return status:  0

C:\gnuCobol>mysql1
libcob: mysql1.cob:17: error: module 'mysql_init' not found

 Last statement of "MySQL1" was CALL at line 17 of mysql1.cob
        ENTRY MySQL1 at mysql1.cob:17
 Started by mysql1

C:\gnuCobol>
--
 PROCEDURE DIVISION.
      * Step 1: Open the MySQL connection
           CALL "mysql_init" USING DB-CONNECTION-HANDLE
           END-CALL
           IF DB-CONNECTION-HANDLE = 0
               DISPLAY "Failed to initialize MySQL connection."
               STOP RUN
           END-IF

有人知道问题出在哪里吗?

mysql c api interface gnucobol
1个回答
0
投票

这个

cobc
使用
gcc
(和
ld
)进行编译/链接,所以这就是当前发生的情况:

您的程序对 C 入口点执行动态

CALL
(这是 GnuCOBOL 的默认设置)。
您链接包含此入口点的库。
链接器发现该入口点从未被调用,因此对其进行了优化,并删除了完整的库,因为没有留下任何单一用途。
COBOL 运行时尝试解析所有加载的库中的入口点(libmsql 不再在那里 - 您可以通过使用 Dependency 分析生成的可执行文件来验证这一点),然后尝试在所有预加载的模块中找到它(您没有),然后尝试打开具有该名称的共享对象,但该对象不存在。

选项:

  1. 保持动态

    CALL
    ,预加载库:
    cobc -d -v -x -o mysql1 mysql1.cob
    (不再有 mysql 的链接选项) 可能在程序中捕获这个(如果你不想硬中止):
    CALL "mysql_init" USING DB-CONNECTION-HANDLE ON EXCEPTION CONTINUE.

    set COB_PRE_LOAD=libmysql
    set COB_LIBRARY_PATH=%COB_LIBRARY_PATH%;C:\Program Files\MySQL\MySQL Server 8.0\lib
    (如果里面有libmysql.dll,否则调整)、
    mysql1

  2. 更改为静态

    CALL
    这需要
    -L"\Program Files\MySQL\MySQL Server 8.0\lib" -lmysql
    ,然后通过以下之一调整
    CALL

    1. CALL STATIC "mysql_init"
      (包括该库中所有其他入口点的调用约定“STATIC”)
    2. CALL "mysql_init"
      cobc -K mysql_init
      (包括所有其他入口点的“-K”)
    3. CALL "mysql_init"
      cobc --static
      (要强制动态加载,例如对于 COBOL 模块,您需要将它们更改为
      MOVE "PROG" TO variable. CALL variable.
  3. 保持动态

    CALL
    并使用
    cobc -Q "-Wl,--no-as-needed"

    禁用链接器优化

注 1:确保您调用的库使用相同的架构(该路径中的 MySQL 库可能是 x64 - 不确定您的 GnuCOBOL 是否使用相同的架构)。

注2:如果你只是从SQL部分开始,我建议考虑不直接调用MySQL库,而是使用标准的SQL预处理器

EXEC SQL

虽然这消除了低级调用的选项,但它非常可移植,并且还允许稍后轻松更改数据库目标(例如更改为 ODBC 或 PostgreSQL)。 GixSQL 是一个非常便携的选项,它还提供 Windows 二进制安装程序

© www.soinside.com 2019 - 2024. All rights reserved.