0

我正在尝试在 OS X 上编译一个简单的 Oracle 应用程序并遇到链接问题。任何帮助,将不胜感激。

#include <iostream>
#include <occi.h>

using namespace std;
using namespace oracle::occi;

Environment * env;
Connection * conn;

int main(int argc, char ** argv)
{
    env = Environment::createEnvironment(Environment::OBJECT);
    conn = env->createConnection("scott", "tiger", "//lcoalhost:1521/xe");
    Statement *stmt = conn->createStatement("SELECT COUNT(*) FROM TAB");
    ResultSet *rs=stmt->executeQuery();
    rs->next();
    string ntabs=rs->getString(1);
    cout << "Number of tables " << ntabs << endl;
    conn->terminateStatement(stmt);
    // Close connection etc
    env->terminateConnection(conn);
    Environment::terminateEnvironment(env);
    return 0;
}

我安装了 x64 oracle 即时客户端~/oracle_clientsqlplus我可以使用和连接到数据库python (cx_Oracle)

我正在使用以下命令编译文件

gcc main.cpp -I ~/oracle_client/sdk/include/ -L ~/oracle_client -locci -lclntsh

以下是ld我收到的错误:

ld: warning: ignoring file <ORACLE_HOME >/libclntsh.dylib, file was built for unsupported file format ( 0x62 0x6f 0x6f 0x6b 0x 0 0x 0 0x 0 0x 0 0x6d 0x61 0x72 0x6b 0x 0 0x 0 0x 0 0x 0 ) which is not the architecture being linked (x86_64): <ORACLE_HOME>/libclntsh.dylib
Undefined symbols for architecture x86_64:
"std::allocator::allocator()", referenced from:
_main in ccWf4dno.o
"std::allocator::~allocator()", referenced from:
_main in ccWf4dno.o
"std::basic_ostream >::operator >& (*)(std::basic_ostream >&))", referenced from:
_main in ccWf4dno.o
"std::basic_string, std::allocator >::basic_string(char const*, std::allocator const&)", referenced from:
_main in ccWf4dno.o
"std::basic_string, std::allocator >::~basic_string()", referenced from:
_main in ccWf4dno.o
"std::ios_base::Init::Init()", referenced from:
__static_initialization_and_destruction_0(int, int)in ccWf4dno.o
"std::ios_base::Init::~Init()", referenced from:
___tcf_0 in ccWf4dno.o
"std::cout", referenced from:
_main in ccWf4dno.o
"std::basic_ostream >& std::endl >(std::basic_ostream >&)", referenced from:
_main in ccWf4dno.o
"std::terminate()", referenced from:
_main in ccWf4dno.o
"std::basic_ostream >& std::operator >(std::basic_ostream >&, char const*)", referenced from:
_main in ccWf4dno.o
"std::basic_ostream >& std::operator, std::allocator >(std::basic_ostream >&, std::basic_string, std::allocator > const&)", referenced from:
_main in ccWf4dno.o
"___gxx_personality_v0", referenced from:
Dwarf Exception Unwind Info (__eh_frame) in ccWf4dno.o
ld: symbol(s) not found for architecture x86_64
collect2: ld returned 1 exit status
4

2 回答 2

1
Undefined symbols for architecture x86_64:
"std::allocator::allocator()", referenced from:
_main in ccWf4dno.o
[...]

所有这些未定义的符号都是 C++ 运行时支持库函数,与 Oracle 无关。让 GCC 引入这些的最简单和最好的方法是将 C++ 代码与g++命令链接,而不是gcc

g++ main.cpp -I ~/oracle_client/sdk/include/ -L ~/oracle_client -locci -lclntsh

链接器关于libclntsh.dylib的架构警告只是警告,因此您安装的即时客户端可能包含正确的架构以及它所抱怨的内容。无论如何,在摆脱了这些虚假的 C++ 运行时链接问题之后,您将能够更好地调试任何剩余的 Oracle 链接问题。

于 2013-02-26T22:41:09.370 回答
0

乍一看,您要么安装了 32 位即时客户端,在这种情况下,您只能构建 32 位二进制文​​件,因此需要在 ; 中添加一个-m32标志gcc。或者您安装了 64 位即时客户端并且gcc由于某种原因(例如别名)默认为 32 位,在这种情况下您可以使用-m64标志覆盖。

无论哪种方式,您的即时客户端似乎是错误的架构......实际上从x86_64您的错误消息中,您正在以 64 位模式构建,因此您似乎已经安装了 32 位即时客户端。但是您在问题中说您确实安装了 64 位版本,您可以通过以下方式验证(您可能知道):

$ file ~/oracle_client/libclntsh.dylib.11.1

...x86_64如果它是 64 位,它将以结束。由于它没有抱怨libocci.dylib它似乎能够应付,建议一种混合安装。大概您已经为完整版本创建了符号链接libclntsh.dyliblibocci.dylib指向完整.11.1版本。是否有可能libclntsh.dylib指向另一个目录中的 32 位版本?或者您将它作为 32 位复制到该名称,然后将所有内容替换为 64 位版本并错过了手动复制的文件?这显示了什么架构:

$ file ~/oracle_client/libclntsh.dylib

它仍然无法编译,但据我所知,其余错误与 Oracle 无关……正如 John Marshall 指出的那样,只需将命令从 切换到gcc即可g++解决剩余问题。

g++ -m32 main.cpp ...

a.out...如果 32 位即时客户端已正确安装/链接,则创建一个。

只是为了比较,使用带有 64 位构建的 32 位客户端会失败:

$ g++ -m64 main.cpp -I ~/oracle_client32/sdk/include/ -L ~/oracle_client32 -locci -lclntsh
ld: warning: ignoring file /Users/alex/oracle_client32/libocci.dylib, file was built for unsupported file format ( 0xce 0xfa 0xed 0xfe 0x 7 0x 0 0x 0 0x 0 0x 3 0x 0 0x 0 0x 0 0x 6 0x 0 0x 0 0x 0 ) which is not the architecture being linked (x86_64): /Users/alex/oracle_client32/libocci.dylib
ld: warning: ignoring file /Users/alex/oracle_client32/libclntsh.dylib, file was built for unsupported file format ( 0xce 0xfa 0xed 0xfe 0x 7 0x 0 0x 0 0x 0 0x 3 0x 0 0x 0 0x 0 0x 6 0x 0 0x 0 0x 0 ) which is not the architecture being linked (x86_64): /Users/alex/oracle_client32/libclntsh.dylib
Undefined symbols for architecture x86_64:
  "oracle::occi::Environment::createEnvironment(oracle::occi::Environment::Mode, void*, void* (*)(void*, unsigned long), void* (*)(void*, void*, unsigned long), void (*)(void*, void*))", referenced from:
      _main in ccWD5dXB.o
  "oracle::occi::Environment::terminateEnvironment(oracle::occi::Environment*)", referenced from:
      _main in ccWD5dXB.o
ld: symbol(s) not found for architecture x86_64
collect2: ld returned 1 exit status

使用具有 32 位构建的 64 位客户端失败:

$ g++ -m32 main.cpp -I ~/oracle_client64/sdk/include/ -L ~/oracle_client64 -locci -lclntsh
ld: warning: ignoring file /Users/alex/oracle_client64/libocci.dylib, file was built for unsupported file format ( 0xcf 0xfa 0xed 0xfe 0x 7 0x 0 0x 0 0x 1 0x 3 0x 0 0x 0 0x 0 0x 6 0x 0 0x 0 0x 0 ) which is not the architecture being linked (i386): /Users/alex/oracle_client64/libocci.dylib
ld: warning: ignoring file /Users/alex/oracle_client64/libclntsh.dylib, file was built for unsupported file format ( 0xcf 0xfa 0xed 0xfe 0x 7 0x 0 0x 0 0x 1 0x 3 0x 0 0x 0 0x 0 0x 6 0x 0 0x 0 0x 0 ) which is not the architecture being linked (i386): /Users/alex/oracle_client64/libclntsh.dylib
Undefined symbols for architecture i386:
  "oracle::occi::Environment::createEnvironment(oracle::occi::Environment::Mode, void*, void* (*)(void*, unsigned long), void* (*)(void*, void*, unsigned long), void (*)(void*, void*))", referenced from:
      _main in ccuBypLo.o
  "oracle::occi::Environment::terminateEnvironment(oracle::occi::Environment*)", referenced from:
      _main in ccuBypLo.o
ld: symbol(s) not found for architecture i386
collect2: ld returned 1 exit status

但请注意,两者都抱怨这两个库,而不仅仅是libclntsh. 使用 32 位客户端和 32 位构建,或 64 位客户端和 64 位构建,两者都可以工作:

$ g++ -m32 main.cpp -I ~/oracle_client32/sdk/include/ -L ~/oracle_client32 -locci -lclntsh
$ file a.out
a.out: Mach-O executable i386

$ g++ -m64 main.cpp -I ~/oracle_client64/sdk/include/ -L ~/oracle_client64 -locci -lclntsh
$ file a.out
a.out: Mach-O 64-bit executable x86_64
于 2013-02-26T20:52:45.037 回答