5

次の C++ プログラムがあります。

Client.h

#ifndef Client_Client_h
#define Client_Client_h

#include "Client.h"

class Client {

public:
    void f1();
    void f2();
};

#endif

クライアント.cpp

#include <iostream>
#include <stdlib.h>
using namespace std;

#include "Client.h"

void Client::f1(){
    cout << "Client.f1()" << endl;
}

void Client::f2() {
    cout << "Client.f2()" << endl;
}

上記を XCode 4.3 でコンパイルすると、次の名前の静的ライブラリ ファイルが得られます。

libClient.a

別に、main.c があります。

#include <stdio.h>
//
//using namespace std;

int main(){
        // how do I do something like: Client c; c.f1(); c.f2(); 
        // and actually get output ? 
        printf("hello\n");
        return 0;
}

f1() と f2() を呼び出すために必要な手順は何ですか? GCC を使用して静的ライブラリを適切にリンクするにはどうすればよいですか?

これまでのところ、私は試しました:

gcc -lClient.a main.c 

これは私に与えます:

ld: library not found for -lClient.a
collect2: ld returned 1 exit status
4

1 に答える 1

10

これは機能しないか、少なくとも移植可能ではありません。非常に明白なことの 1 つは、プログラムを C++ にして、これらの機能にアクセスできるようにすることです。

明らかな理由から、C コードから C++ コードを「ネイティブに」使用することはできません。オブジェクト指向の機能にアクセスできないため、多くの機能が機能しません。コンストラクタ、デストラクタ、移動/コピー セマンティクス、および仮想継承は、おそらく見逃してしまう最大のものです。(そうです。単純なコンストラクターとデストラクターがない限り、オブジェクトを正しく作成または破棄することはできません。)

リンケージの問題も発生します。C++ 関数名はパラメーターの型、戻り値の型、およびクラスを含むごちゃごちゃになってしまい、次のようになります__1cGstrcpy6Fpcpkc_0_。Cで関数のマングル名を宣言してそれらを使用したり、関数へのポインターを取得したりすることは技術的に実現可能dlsymですが、それはばかげています。そうしないでください。

C から呼び出し可能にする必要がある関数を C++ で作成する必要がある場合は、その関数を として指定するextern "C"と、その名前は変更されず、C からアクセス可能になり、それ自体で C++ 機能を使用できるようになります。

extern "C" void Foo()
{
    std::string hello = "Hello world!";
    std::cout << hello << std::endl;
}

次に、プログラムの C 側で次のように宣言する必要があります。

void Foo();

そして、あなたはそれを呼び出すことができるようになります。

Cプログラムに公開したいすべてのC++呼び出しをextern "C"関数でラップし、型へのポインタを返してそのように処理することは可能ですが、すぐに面倒になります。本当に C++ を使用する必要があります。

スタティック ライブラリとのリンクに関する限り、Xcode でプロジェクト設定に移動し、ターゲットを選択して、[ビルド フェーズ] タブに移動し、[バイナリをライブラリにリンク] セクションを展開して、そこに .a ファイルをドロップします。

于 2013-08-23T04:48:59.250 に答える