我有以下c ++程序:
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;
}
在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
答案 0 :(得分:8)
这不起作用,或者至少不可移植。一个非常显而易见的事情就是让您的程序使用C ++,以便访问这些功能。
出于显而易见的原因,您无法“本地”使用C代码中的C ++代码。您无法访问面向对象的功能,因此大量的东西不会起作用:构造函数,析构函数,移动/复制语义和虚拟继承可能是您将错过的最重要的事情。 (这是正确的:你将无法正确创建或销毁对象,除非它们具有琐碎的构造函数和析构函数。)
您还会遇到链接问题:C ++函数名称为mangled,包括它们的参数类型和返回类型和类,它们看起来像__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 ++调用包装到extern "C"
函数中的C程序中,并返回指向你的类型的指针并以这种方式处理它,但它会变得很烦人很快。你真的应该使用C ++。
就与静态库的链接而言,在Xcode中,转到项目设置,选择目标,转到Build Phases选项卡,展开“Link Binary With Libraries”部分,然后删除.a文件那里。