无法 link 预编译文件

Unable to link pre-compiled file

我使用 OpenVMS V8.4 作为 Oracle 10g 数据库服务器,带有 CXX 内置编译器以及 oracle 提供的 PROC 编译器。

我写了这个示例 C 程序:

sample.c

#include<stdio.h>
exec sql include sqlca;  // adds Oracle PLSQL library
                         // same as #include<sqlca.h>

main() {
    printf("Hello, World!\n");
}

然后我编译了它

DEVSERVER> PROC SAMPLE.C SAMPLE.PC

该命令可以找到,然后我可以使用内置的 CXX 编译器:

DEVSERVER> CXX SAMPLE.PC

该命令没有任何错误,我现在可以使用内置的 LINK 命令:

DEVSERVER> LINK SAMPLE

现在我可以通过以下方式 运行 文件:

DEVSERVER> RUN SAMPLE

我得到了预期的输出:

Hello, World!

所以,没关系。但是我的程序还没有做任何有用的事情。因此,让我们首先连接到数据库模式。 我将 SAMPLE.C 修改为 :

#include<stdio.h>
exec sql include sqlca; 

main() {
    printf("Hello, World!\n");

    exec sql connect scott identified by tiger;
    // I skipped checking for sqlca.error since LINKer wont even allow
    //  me to create EXE of this file
}

现在,我像以前一样预编译:

DEVSERVER> PROC SAMPLE.C SAMPLE2.PC
DEVSERVER> CXX SAMPLE2.PC
DEVSERVER> LINK SAMPLE2

这里是我收到此错误的地方:

%ILINK-W-NUDFSYMS, 1 undefined symbol:
%ILINK-I-UDFSYM,  CX3$Z6SQLCXTPPVPJP6SQLXD384K7FP
%ILINK-W-USEUNDEF, undefined symbol CX3$Z6SQLCXTPPVPJP6SQLXD384K7FP refernced
        source code name: "sqlcxt(void **, unsigned int *, sqlexd *, const sqlcxp *)"
        section: .text
        offset: %X0000000000000350 slot: 2
        module: SAMPLE2
        file: DEV$SERVER[SOURCE]SAMPLE2.OBJ;1

每当我尝试在代码的 exec sql 块中执行任何 SQL 语句时,都会发生同样的错误。

我做错了什么?

您 运行 陷入问题的连锁反应:编译(c++ 名称修改)和链接:

https://docs.oracle.com/cd/E11882_01/server.112/e56697/ch6.htm#VMSAR516

注意 CODE=CPP 参数。这种遗漏可能是您的第一个主要头痛问题。 看起来您是 C++ 名称修改的受害者。您的编译器可能正在翻译

 sqlcxt(void **, unsigned int *, sqlexd *, const sqlcxp *)

进入

 CX3$Z6SQLCXTPPVPJP6SQLXD384K7FP

然后注意文档中链接到 Oracle 库的命令过程。

@user3344003 的回复勾起了我的回忆。 :-) 是的,他是对的——为处理 EXEC SQL 而创建的过程的名称是 name-mangled,但它是由 SQL [=24] 生成的(在汇编程序中,IIRC) =] 你必须稍微解决这个问题。

我们以前处理这个问题的方法是有一个单独的 .c 文件,里面有一堆过程,每个过程要么执行一个 SQL 语句,要么执行一组逻辑语句SQL 条语句需要执行任务。我们还有一个 .h 文件,其原型与 .c 文件中的例程相匹配。 header 将 #included 放入 .cpp 文件中,header 中的函数原型给出适当的 extern "C" 以指定 C 调用约定并且没有名称修改。

另一种我从未尝试过但可能有效的可能性是将 sqlcxt(void **, unsigned int *, sqlexd *, const sqlcxp *) 的原型简单地放入您的代码中,并以 extern "C" 开头。可能值得一试,但我只能保证 .c 文件方法。

祝你好运。

只需在您的 OpenVMS 服务器上使用 C 编译器,它很可能也已安装。 Oracle 的 ProC 也是 C,所以您不会处理很多 CXX 怪癖。除非,还有其他未提及的因素要求您使用 C++...

至于 CXX,根据您使用的版本,过去曾要求使用 CXXLINK 而不是 LINK 命令来链接 C++ 代码。显然,混合使用 C 和 C++ 代码时,您需要注意代码中定义的 C 函数 extern "C"