簡體   English   中英

在C中使用帶有命名空間的C ++

[英]using C++ with namespace in C

在Linux上使用Eclpse我已經定義了一個名為ABC(ABC.hpp)的C ++類:

#ifndef ABC_HPP_
#define ABC_HPP_

#include <stdio.h>

// namespace my {            <---- COMMENTED OUT

class ABC {
private:
    int m_number;
public:
    ABC(int p_number);
    void doSomething();
    virtual ~ABC();
};

// } /* namespace my */      <---- COMMENTED OUT

#endif /* ABC_HPP_ */

它的實現是(ABC.cpp):

#include "ABC.hpp"

// using namespace my;       <---- COMMENTED OUT

ABC::ABC(int p_number) {
    this->m_number = p_number;
}

ABC::~ABC() {
    this->m_number = -1;
}

void ABC::doSomething() {
    printf("doing something (%d)\n", this->m_number);
}

要在C程序中使用此類,我創建了一個包含這些方法的層(ABCwrapper.h):

typedef void CABC;

#ifdef __cplusplus
extern "C" {
#endif

CABC* create_abc();
void call_abc_methods(const CABC *p_abc);
void destroy_abc(CABC *p_abc);

#ifdef __cplusplus
} // extern "C"
#endif

#include "ABC.hpp"
#include "ABCWrapper.h"

extern "C" {

CABC* create_abc() {
    ABC* abc = new ABC();
    return (ABC*)abc;
}

void call_abc_methods(const CABC *p_abc) {
    ABC* abc = (ABC*)p_abc;
    abc->doSomething();
}

void destroy_abc(CABC *p_abc) {
    ABC* abc = (ABC*)p_abc;
    delete abc;
}

}

那很好,我可以使用ABC類實例。 但是如何在名稱空間中定義ABC類,讓我們說“我的”? 如果我從所有名稱空格行中刪除注釋符號,IDE會抱怨說“類型'ABC'無法解析”。

如果我想擴展我的C ++庫,我必須為我的類使用名稱空間,但后來我不知道如何在包裝器中使用。 拜托,幫我解開這個謎。

謝謝。

SK

ABCWrapper.cpp ,在extern "C" { line,上面添加:

using my::ABC;

要么

using namespace my;

約翰的建議(用ABCWrapper.cpp my::ABC替換ABC所有實例)也有效。

關於代碼的一些主要是次要的挑剔。 您已經獲得了具有活動命名空間的解決方案的詳細信息,但是應該解決各種小問題。

你最好引入一個不完整的類型, typedef struct CABC CABC; (代替typedef void CABC; ),以便在C代碼中獲得某種類型的安全性。 這會阻止您將隨機FILE *傳遞給C接口函數,而使用void函數則不會。

當您使用不完整類型時,您應該在C包裝函數中使用reinterpret_cast<ABC *>(abc)而不是C樣式轉換。 編譯器然后在call_abc_methods()函數中顯示const-ness的問題; 參數不應該是const (但C風格的轉換隱藏了問題)。

此外,您的ABC.hpp標題顯示常見(次要)錯誤; 它包含一個無關的頭文件( #include <stdio.h> ),安全使用頭文件不需要它。 該行應僅出現在實現文件ABC.cpp ,其中代碼使用<stdio.h>的服務。 大多數標題應該#include只包含使標題可單獨使用所需的其他標題。 它們不應包含隨機的其他標題。

這是一個完整的工作程序 - 它有很多文件。 有3個標題:

  • ABC.hpp - 聲明class ABC
  • ABCwrapper.h - 將C接口聲明為class ABC
  • ABCprogram.h - 雙語標題聲明其他功能。

有1個C文件:

  • ABCuser.c - 必須有一些C代碼需要使用C接口來class ABC才能使整個練習變得有價值,就是這樣。

有3個C ++文件:

  • ABC.cpp - 定義class ABC
  • ABCwrapper.cpp - 定義class ABC的C接口。
  • ABCmain.cpp - 雙語系統中的主程序通常應該用C ++編寫。

還有一個makefile

ABC.hpp

#ifndef ABC_HPP_INCLUDED
#define ABC_HPP_INCLUDED

namespace abc_library {

class ABC {
private:
    int m_number;
public:
    ABC(int p_number);
    void doSomething();
    virtual ~ABC();
};

} /* namespace abc_library */

#endif /* ABC_HPP_INCLUDED */

ABCwrapper.h

#ifndef ABCWRAPPER_H_INCLUDED
#define ABCWRAPPER_H_INCLUDED

typedef struct CABC CABC;   // Pointer to this ncomplete type used in C code

#ifdef __cplusplus
extern "C" {
#endif

CABC *create_abc(int val);
void call_abc_methods(CABC *p_abc);
void destroy_abc(CABC *p_abc);

#ifdef __cplusplus
}
#endif

#endif /* ABCWRAPPER_H_INCLUDED */

ABCprogram.h

#ifndef ABCPROGRAM_H_INCLUDED
#define ABCPROGRAM_H_INCLUDED

#if defined(__cplusplus)
extern "C" {
#endif

extern int c_code_function(int init);

#if defined(__cplusplus)
}
#endif

#endif /* ABCPROGRAM_H_INCLUDED */

ABCuser.c

#include "ABCwrapper.h"
#include "ABCprogram.h"

int c_code_function(int init)
{
    CABC *abc = create_abc(init);
    call_abc_methods(abc);
    destroy_abc(abc);
    return 0;
}

ABC.cpp

#include "ABC.hpp"
#include <stdio.h>

using namespace abc_library;

ABC::ABC(int p_number) {
    this->m_number = p_number;
}

ABC::~ABC() {
    this->m_number = -1;
}

void ABC::doSomething() {
    printf("doing something (%d)\n", this->m_number);
}

ABCwrapper.cpp

#include "ABC.hpp"
#include "ABCwrapper.h"

using namespace abc_library;

extern "C" {

CABC *create_abc(int val) {
    ABC* abc = new ABC(val);
    return reinterpret_cast<CABC*>(abc);
}

void call_abc_methods(CABC *p_abc) {
    ABC *abc = reinterpret_cast<ABC *>(p_abc);
    abc->doSomething();
}

void destroy_abc(CABC *p_abc) {
    ABC* abc = reinterpret_cast<ABC *>(p_abc);
    delete abc;
}

}

ABCmain.cpp

#include "ABCprogram.h"

int main()
{
   return c_code_function(39);
}

生成文件

CC     = gcc # /usr/bin/gcc
CXX    = g++
RM_FR  = rm -fr --
WFLAGS = -Wall -Wextra -Wmissing-prototypes -Wstrict-prototypes -Wold-style-definition
SFLAGS = -std=c99
OFLAGS = -g -O3
UFLAGS = # Set on make command line only

OXXFLAGS = -g -O3
SXXFLAGS = -std=c++11
WXXFLAGS = -Wall -Wextra
UXXFLAGS = # Set on make command line only

LDFLAGS =
LDLIBS  =

CFLAGS   = ${OFLAGS}   ${SFLAGS}   ${WFLAGS}   ${UFLAGS}
CXXFLAGS = ${OXXFLAGS} ${SXXFLAGS} ${WXXFLAGS} ${UXXFLAGS}

PROGRAM = abc

FILES.cpp = \
        ABC.cpp \
        ABCmain.cpp \
        ABCwrapper.cpp
FILES.c = \
        ABCuser.c
FILES.h = \
        ABCprogram.h \
        ABCwrapper.h

FILES.o = ${FILES.cpp:.cpp=.o} ${FILES.c:.c=.o}

all: ${PROGRAM}

${PROGRAM}: ${FILES.o}
        ${CXX} -o $@ ${CXXFLAGS} ${FILES.o} ${LDFLAGS} ${LDLIBS}

clean:
        ${RM_FR} *.o *.dSYM core a.out

depend:
        mkdep ${FILES.cpp} ${FILES.c}

# DO NOT DELETE THIS LINE or the blank line after it -- make depend uses them.

ABC.o: ABC.cpp
ABC.o: ABC.hpp
ABCmain.o: ABCmain.cpp
ABCmain.o: ABCprogram.h
ABCuser.o: ABCprogram.h
ABCuser.o: ABCuser.c
ABCuser.o: ABCwrapper.h
ABCwrapper.o: ABC.hpp
ABCwrapper.o: ABCwrapper.cpp
ABCwrapper.o: ABCwrapper.h

您必須為ABC類設置范圍。 因此,除了類聲明之外,將所有ABC類替換為我的:: ABC。

  extern "C" {

  CABC* create_abc() {
       my::ABC* abc = new my::ABC();
       return (my::ABC*)abc;
  }

  void call_abc_methods(const CABC *p_abc) {
     my::ABC* abc = (my::ABC*)p_abc;
     abc->doSomething();
  }

  void destroy_abc(CABC *p_abc) {
      my::ABC* abc = (my::ABC*)p_abc;
      delete abc;
  }

}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM