我正在尝试在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;
}
我在~/oracle_client
安装了x64 oracle即时客户端。我可以使用sqlplus
和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
答案 0 :(得分: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链接问题。
答案 1 :(得分:0)
乍一看,您似乎安装了32位即时客户端,在这种情况下,您只能构建32位二进制文件,因此需要向-m32
添加gcc
标记;或者您安装了64位即时客户端,gcc
由于某种原因(例如别名)默认为32位,在这种情况下,您可以使用-m64
标记覆盖。
无论哪种方式,您的即时客户端出现都是错误的架构......实际上,从错误消息中的x86_64
开始,您构建的是64位模式,因此你好像已经安装了32位即时客户端。但是你在问题中说你确实安装了64位版本,你可以用它验证(你可能知道):
$ file ~/oracle_client/libclntsh.dylib.11.1
...如果是64位,将以x86_64
结尾。由于它没有抱怨libocci.dylib
它似乎能够应付这一点,建议采用一种混合装置。据推测,您已为libclntsh.dylib
和libocci.dylib
创建了指向完整.11.1
版本的符号链接。 libclntsh.dylib
是否可能指向另一个目录中的32位版本;或者您将其作为32位复制到该名称,然后用64位版本替换所有内容并错过了手动复制的文件?这显示了什么架构:
$ file ~/oracle_client/libclntsh.dylib
它仍然无法使用已整理的编译进行编译,但就我所知,其余的错误与Oracle无关......正如John Marshall指出的那样,只需将命令从gcc
切换到g++
解决了剩余的问题。
g++ -m32 main.cpp ...
...如果正确安装/链接32位即时客户端,则创建a.out
。
仅用于比较,使用具有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