代码之家  ›  专栏  ›  技术社区  ›  lImbus

如何调用C++编写的LIB?

  •  2
  • lImbus  · 技术社区  · 14 年前

    在我看来,这似乎是一个毫不费力的,但我找不到任何反对或支持它的信息。

    我现在在linux上,尝试使用静态绑定。

    我甚至不知道这是否可行,更不用说怎么做了。

    7 回复  |  直到 14 年前
        1
  •  8
  •   Oliver Charlesworth    14 年前

    通常,您需要强制C++编译器为导出函数使用C链接构建库。

    #ifdef __cplusplus
    extern "C" {
    #endif
    
    void func(void);
    
    /* ... Other function defs go here ... */
    
    #ifdef __cplusplus
    }
    #endif
    

    通常,链接器会对函数进行C++名称的修改,从而使C链接器无法找到它们。 extern "C" 强迫它不要那样做。你得把它包在 #ifdef ,因为 外部“C” 在C中无效。

    更新

        2
  •  4
  •   Å imon Tóth    14 年前

    如果C++库不提供C接口,那么你就不能。

    如果您是作者,请使用 extern "C" 特征。 http://www.parashift.com/c++-faq-lite/mixing-c-and-cpp.html

        3
  •  3
  •   Arafangion    14 年前

    就个人而言,我将编写一个C++文件,导出使用C链接的函数。换句话说,写一个绑定。

        4
  •  2
  •   Edgar Bonet    14 年前

    在Linux上,您可以使用命令获取C++函数的损坏名称

    nm my-tiny-c++lib.a
    

    编辑 :然后必须使用g++或gcc-lstdc链接++

        5
  •  2
  •   Prof. Falken    14 年前

    从需求的角度来看,这是一个问题。使用 extern C 在C++中,你想从C.调用

    Mangling and de-mangling 由于C++过于依赖于平台,所以在C++中从来没有标准化。结果是,尽管您可以通过查看链接器输出来计算C++方法的名称,但是没有可找到的方法来找到C++函数方法的“实际”可链接名称。

        6
  •  1
  •   CashCow    14 年前

    你甚至可以使用C++类。您主动声明它们为struct。如果执行此操作,某些编译器将发出警告,但您可能可以禁用此警告或忽略它。

    请注意,如果类位于命名空间中,则无法执行此操作,因此请创建仅包含该成员的自己的结构并使用该“包装器”。

    #ifdef __cplusplus
    extern "C" {
    #endif
    
    // all your functions
    
    #ifdef __cplusplus
    }
    #endif
    
        7
  •  0
  •   Vovanium    14 年前

    典型的包装如下:

    #include "class_a_wrapper"
    
    class A {
         public:
         int foo(double p);
         double bar(int x, int y);
    }
    

    ----类包装----

    #ifdef __cplusplus
    extern "C" {
    #endif
    
    struct wrap_A;
    int wrap_A_foo(struct wrap_A *obj, double p);
    double wrap_A_bar(struct wrap_A *obj, int x, int y);
    
    #ifdef __cplusplus
    }
    #endif
    

    ----类包装.cpp----

    #include "class_a.hpp"
    
    int wrap_A_foo(struct wrap_A *obj, double p) {
        return (static_cast<A*>obj)->foo(p);
    }
    double wrap_A_bar(struct wrap_A *obj, int x, int y) {
        return (static_cast<A*>obj)->bar(x, y);
    }