无法链接预编译文件

时间:2018-05-10 13:06:07

标签: c plsql openvms

我使用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

我得到了预期的输出:

  

你好,世界!

所以,这一切都很好。但我的程序还没有做任何有用的事情。因此,我们首先连接到数据库模式。 我将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语句时,都会发生同样的错误。

我做错了什么?

3 个答案:

答案 0 :(得分:1)

您遇到了问题的连锁反应:编译(c ++名称修改)和链接:

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

请注意CODE = CPP参数。遗漏可能是你头痛的第一次。 看起来你是C ++名称修改的受害者。您的编译器可能正在翻译

id()

进入

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

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

答案 1 :(得分:1)

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

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

答案 2 :(得分:0)

@ user3344003的回复带回了回忆。 :-)是的,他是正确的 - 为处理EXEC SQL而创建的过程的名称正在被命名,但是它由SQL预生成(在汇编程序,IIRC中) - 处理器你必须解决这个问题。

我们过去常常处理这个问题的方法是使用一个单独的.c文件和一堆程序,每个程序执行一个SQL语句或执行一个SQL语句的逻辑组。任务。我们还有一个带有原型的.h文件,它与.c文件中的例程相匹配。标题将是#include到.cpp文件中,标题中的函数原型给出了适当的extern "C"来指定C调用约定而没有名称重整。

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

祝你好运。