在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_ */
Run Code Online (Sandbox Code Playgroud)
它的实现是(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);
}
Run Code Online (Sandbox Code Playgroud)
要在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
Run Code Online (Sandbox Code Playgroud)
和
#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;
}
}
Run Code Online (Sandbox Code Playgroud)
那很好,我可以使用ABC类实例.但是如何在名称空间中定义ABC类,让我们说"我的"?如果我从所有名称空格行中删除注释符号,IDE会抱怨说"类型'ABC'无法解析".
如果我想扩展我的C++库,我必须为我的类使用名称空间,但后来我不知道如何在包装器中使用.拜托,帮我解开这个谜.
谢谢.
SK
关于代码的一些主要是次要的挑剔.您已经获得了具有活动命名空间的解决方案的详细信息,但是应该解决各种小问题.
您最好引入一个不完整的类型typedef struct CABC CABC;(代替typedef void CABC;),以便在C代码中获得某种类型的安全性.FILE *例如,这会阻止您将随机传递给C接口函数,而这些函数void不会使用.
当您使用不完整类型时,您应该reinterpret_cast<ABC *>(abc)在C包装函数中使用而不是C样式转换.编译器然后在call_abc_methods()函数中显示const-ness的问题; 这个论点不应该是const(但C风格的演员隐藏了这个问题).
此外,您的ABC.hpp标题显示常见(次要)错误; 它包括一个无关的header(#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- 定义C接口class ABC.ABCmain.cpp - 双语系统中的主程序通常应该用C++编写.还有一个makefile.
#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 */
Run Code Online (Sandbox Code Playgroud)
#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 */
Run Code Online (Sandbox Code Playgroud)
#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 */
Run Code Online (Sandbox Code Playgroud)
#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;
}
Run Code Online (Sandbox Code Playgroud)
#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);
}
Run Code Online (Sandbox Code Playgroud)
#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;
}
}
Run Code Online (Sandbox Code Playgroud)
#include "ABCprogram.h"
int main()
{
return c_code_function(39);
}
Run Code Online (Sandbox Code Playgroud)
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
Run Code Online (Sandbox Code Playgroud)
在ABCWrapper.cpp,上述extern "C" {线,添加:
using my::ABC;
Run Code Online (Sandbox Code Playgroud)
要么
using namespace my;
Run Code Online (Sandbox Code Playgroud)
约翰的建议(ABC用my::ABCin 替换所有实例ABCWrapper.cpp)也有效.
| 归档时间: |
|
| 查看次数: |
3488 次 |
| 最近记录: |