【问题标题】:How do you link a C++ static library to a C program?如何将 C++ 静态库链接到 C 程序?
【发布时间】:2013-08-26 00:44:53
【问题描述】:

我有以下 c++ 程序:

客户端.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

【问题讨论】:

  • 我认为这行不通,您的目标程序可能需要是 C++
  • 那么根本就没有从 C 程序调用 C++ 功能的聪明方法吗?
  • 您可以将其包装到库中的一个函数中。 extern "C" void invoke_f1(); 并将其导出。
  • @user1068636 使用-lClient,而不是-lClient.a,加载libClient.a。

标签: c++ c gcc xcode4


【解决方案1】:

这行不通,或者至少不能移植。一件真正显而易见的事情是让你的程序变成 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 程序的所有 C++ 调用包装在 extern "C" 函数中,并返回一个指向你的类型的指针并以这种方式处理它,但它很快就会变得烦人.你真的应该只使用 C++。

就与静态库的链接而言,在 Xcode 中,转到您的项目设置,选择您的目标,转到 Build Phases 选项卡,展开“Link Binary With Libraries”部分,然后放下您的 .a 文件在那里。

【讨论】:

  • 这是正确的方法。如果应用程序必须用 C 编写,库必须用 C++ 编写,无论出于何种原因,您都需要将库接口代码包装成 C 可以理解的代码。
猜你喜欢
  • 1970-01-01
  • 2013-10-04
  • 2012-02-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多