在C ++中调用当前命名空间之外的函数

时间:2014-07-16 14:32:13

标签: c++ c namespaces

我正在尝试从我的CPP代码调用C文件中定义的函数,我认为我在获取正确的命名空间时遇到问题。编译时我收到错误:“未定义引用'获取'”。

我的C标题:

// c.h
#ifndef C_H
#define C_H

#ifdef __cplusplus
    extern "C" {
#endif

typedef enum
{
    VAL_A1,
    VAL_A2
} TYPE_A;

typedef enum
{
    VAL_B1,
    VAL_B2
} TYPE_B;

typedef enum
{
    VAL_C1,
    VAL_C2
} TYPE_C;

typedef struct
{
    TYPE_B b;
    TYPE_C c;
} TYPE_D;

TYPE_A Get(TYPE_B b, TYPE_D *d);

#ifdef __cplusplus
    }
#endif

#endif

我的CPP文件:

// main.cpp
...

extern "C" {
    #include "c.h"
}

...

namespace MyNamespace
{
    ...

    MyClass::MyFunc()
    {
        TYPE_D d;
        // None of these calls will compile
        // Get(VAL_B1, &d);
        // ::Get(VAL_B1, &d);
    }

    ...
}

我试过没有命名空间引用的调用,也尝试使用"::"使用“root”命名空间而没有运气。任何帮助表示赞赏。我已经读完了这个似乎澄清了它,但我真的不明白它:

using C++ with namespace in C

3 个答案:

答案 0 :(得分:2)

"未定义的参考"表示该函数已声明(在标题中),但未定义。您需要在某个源文件中定义函数(可能是您引用的C文件),并确保在构建程序时链接该文件。

答案 1 :(得分:0)

首先,让我们注意一下这个错误意味着什么。链接器阶段的未定义引用意味着编译器无法找到某个实例。在这种情况下,执行一个函数。

让我们看一下您的代码..我们需要添加一些内容以使其可编辑:

  • Get()的定义。
  • main()
  • MyClass
  • 的类定义

一旦我们添加了这三个修复程序,代码就会编译而不会出错。

extern "C" { extern "C" {
    typedef enum {
        VAL_A1,
        VAL_A2
    } TYPE_A;

    typedef enum {
        VAL_B1,
        VAL_B2
    } TYPE_B;

    typedef enum {
        VAL_C1,
        VAL_C2
    } TYPE_C;

    typedef struct {
        TYPE_B b;
        TYPE_C c;
    } TYPE_D;

    TYPE_A Get(TYPE_B b, TYPE_D *d) {
        return VAL_A1;
    }
}}

namespace MyNamespace {
    struct MyClass {
        void MyFunc();
    };

    void MyClass::MyFunc() {
        TYPE_D d;

        Get(VAL_B1, &d);
        ::Get(VAL_B1, &d);
    }
}

int main() {}

答案 2 :(得分:0)

Get的定义(未在问题中显示)也需要包含在extern "C"中。

在实践中,C和C ++函数之间的主要区别在于它们以可执行格式命名。 C ++函数通过链接器进行“名称修改”处理,但C函数则不然。链接器将看到Get的C ++定义,并且它不知道它与C声明的关系,即使它们具有相同的签名。