如何正确混合C ++和C [英] How to mix C++ and C correctly

查看:128
本文介绍了如何正确混合C ++和C的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我遇到一些问题:我需要为C ++库编写一个C包装。说我有3个档案:

I am having some problems with this: I need to write a C wrapper for a C++ library. Say I have 3 files:


  • wrapper.h

  • wrapper.h

typedef struct Foo Foo;
Foo* create_foo();


  • wrapper.cpp

  • wrapper.cpp

    extern "C" {
        #include "wrapper.h"
    }
    #include "foo.h"
    
    Foo* create_foo() {
        return new Foo;
    }
    


  • foo.h

  • foo.h

    class Foo {
    public:
        Foo();
    };
    


  • 这会编译得很好:

    clang ++ -std = c ++ 14 wrapper.cpp foo.h wrapper.h -shared -fPIC

    clang ++ -shared -o libbindings.so a.out

    编译使用C包装器的程序(它是编译器,并由使用包装器的编程语言 - Crystal)链接,我得到一个未定义的create_foo()和一个链接器错误 collect2:error:ld返回1退出状态

    but when compiling the program that uses the C wrapper (it is compiler and linked by the programming language that uses the wrapper - Crystal), I get an undefined reference to create_foo() and a linker error collect2: error: ld returned 1 exit status. How can I debug this (and what am I doing wrong)?

    推荐答案

    这是一个工作示例:

    wrapper.h (了解C& C ++)

    wrapper.h (C & C++ aware)

    #ifndef WRAPPER_H_
    #define WRAPPER_H_
    
    #ifdef __cplusplus
    extern "C" {
    #endif
    
    typedef struct CPPClass CPPClass;
    
    CPPClass* CPPClass_new();
    void CPPClass_do_something(CPPClass* cppclass);
    int CPPClass_get_state(CPPClass* cppclass);
    void CPPClass_delete(CPPClass* cppclass);
    
    #ifdef __cplusplus
    }
    #endif
    #endif /* WRAPPER_H_ */
    

    wrapper.cpp (仅限C ++)

    #include "wrapper.h"
    
    class CPPClass
    {
        int state;
    public:
        CPPClass(): state(0) {}
        void do_something() { ++state; }
        int get_state() const { return state; }
    };
    
    extern "C" CPPClass* CPPClass_new()
    {
        return new CPPClass;
    }
    
    extern "C" void CPPClass_do_something(CPPClass* cppclass)
    {
        cppclass->do_something();
    }
    
    extern "C" int CPPClass_get_state(CPPClass* cppclass)
    {
        return cppclass->get_state();
    }
    
    extern "C" void CPPClass_delete(CPPClass* cppclass)
    {
        delete cppclass;
    }
    

    use-wrapper.c

    #include <stdio.h>
    #include "wrapper.h"
    
    int main(void)
    {
        CPPClass* cppclass = CPPClass_new();
    
        if(!cppclass)
        {
            printf("ERROR: failed to create CPPClass:\n");
            return 1;
        }
    
        printf("state: %d\n", CPPClass_get_state(cppclass));
        CPPClass_do_something(cppclass);
        printf("state: %d\n", CPPClass_get_state(cppclass));
    
        CPPClass_delete(cppclass);
    }
    

    编译CPP

    g++ -std=c++11 -shared -fPIC -c -o libwrapper.so wrapper.cpp
    

    编译C

    gcc -o use-wrapper use-wrapper.c -L. -lwrapper -lstdc++
    

    输出

    $ ./use-wrapper 
    state: 0
    state: 1
    

    希望有帮助。

    这篇关于如何正确混合C ++和C的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆