Question

I have the following c++ program:

Client.h

#ifndef Client_Client_h
#define Client_Client_h

#include "Client.h"

class Client {

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

#endif

Client.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;
}

compiling the above in XCode 4.3 gives me a static library file called:

libClient.a

Separately, I have 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;
}

What's steps do I need to take in order to invoke f1() and f2() ? How do I use GCC to link the static library properly?

So far I have tried:

gcc -lClient.a main.c 

which gives me :

ld: library not found for -lClient.a
collect2: ld returned 1 exit status
Était-ce utile?

La solution

This isn't going to work, or at least is not going to be portable. The one really really obvious thing to do is to make your program C++ so you can access those features.

You can't "natively" use C++ code from C code, for obvious reasons. You don't have access to object-oriented features, so a ton of stuff isn't going to work: constructors, destructors, move/copy semantics and virtual inheritance are probably the biggest things that you'll miss. (That's right: you won't be able to create or destroy objects correctly, unless they have trivial constructors and destructors.)

You'll also run into linkage issues: C++ function names are mangled into a mess that includes their parameter types and return types and classes, which will look like __1cGstrcpy6Fpcpkc_0_. It would be technically feasible to declare the mangled names of the functions in C to use them, or use dlsym to get a pointer to them, but that's plain silly. Don't do that.

If you need to create a function in C++ that needs to be callable from C, you can specify it as extern "C" and its name won't be mangled, and it will be accessible from C, and it will be itself able to use C++ features:

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

You will then need to declare it on the C side of your program like this:

void Foo();

And you'll be able to call it.

It's possible for you to wrap all your C++ calls that you want to expose to your C program in extern "C" functions, and return a pointer to your type and deal with it that way, but it's going to get annoying very quickly. You really should just use C++.

As far as linking with the static library is concerned, in Xcode, go to your project settings, pick your target, go to the Build Phases tab, unfold the "Link Binary With Libraries" section, and drop your .a file there.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top