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_clientます。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
4

2 に答える 2

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

これらの未定義シンボルはすべて C++ ランタイム サポート ライブラリ関数であり、Oracle とは関係ありません。GCC にこれらを取り込む最も簡単で最良の方法は、次のg++コマンドではなく、C++ コードをコマンドにリンクすること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 ビットの Instant Client をインストールしたように見えます。この場合、32 ビットのバイナリしかビルドできないため、-m32フラグをに追加する必要がありgccます。または、64 ビットの Instant Client をインストールし、gcc何らかの理由 (エイリアスなど) でデフォルトを 32 ビットに設定している場合。この場合、-m64フラグでオーバーライドできます。

いずれにせよ、あなたのインスタント クライアント間違ったアーキテクチャのようです...そして実際にはx86_64エラー メッセージから、64 ビット モードでビルドしているため、32 ビットのインスタント クライアントがインストールされているようです。しかし、あなたは質問で、64ビットバージョンをインストールしたと言いました。これは(おそらくご存知のように)次の方法で確認できます。

$ file ~/oracle_client/libclntsh.dylib.11.1

... x86_6464ビットの場合は終了します。不満はないので、そこまではlibocci.dylib対応できそうで、一種のハイブリッド装着を示唆している。おそらく、フルバージョンへのシンボリックリンクを作成し、フルバージョンlibclntsh.dyliblibocci.dylib指しているでしょう。別のディレクトリにある 32 ビット バージョンを指して.11.1いる可能性はありますか。libclntsh.dylibまたは、32ビットとしてその名前にコピーしてから、すべてを64ビットバージョンに置き換えて、手動でコピーしたファイルを見逃していましたか? これが示すアーキテクチャは次のとおりです。

$ file ~/oracle_client/libclntsh.dylib

それはまだ整理されていませんが、残りのエラーは私が知る限りOracleに関連していません...そしてJohn Marshallが指摘したように、残りの問題gccを解決するためにコマンドを切り替えるだけです。g++

g++ -m32 main.cpp ...

... a.out32 ビットのインスタント クライアントが正しくインストール/リンクされている場合に作成します。

比較のために、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 に答える