首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用c++程序中的extern包括在c++中构建的头文件

使用c++程序中的extern包括在c++中构建的头文件
EN

Stack Overflow用户
提问于 2020-08-03 13:34:42
回答 2查看 137关注 0票数 0

我在C++中有一个类,我想利用它创建一个共享库,并使用C语言或其他语言。这是我想从它创建一个库的类:

getinfo.h

代码语言:javascript
复制
#ifndef GETINFO_H
#define GETINFO_H
#include "info.h"

char* getMaximumSpeedCpu();
char* getCoreNumbers();
#endif

getinfo.cpp:

代码语言:javascript
复制
#include <iostream>
#include "getinfo.h"
using namespace Morsa::Prd::SMC::SL;
char* getMaximumSpeedCpu()
{
    info *inf = new info;
    std::string str = inf->maximumSpeedCpu();
    char* maxspeed = new char[str.length()+1];
    strcpy(maxspeed, str.c_str());
    free(inf);
    return maxspeed;
}
char* getCoreNumbers()
{
    info *inf = new info;
    std::string corenum = inf->coreNumbers();
    char* num = new char[corenum.length()+1];
    strcpy(num, corenum.c_str());
    free(inf);
    return num;
}

这是我的包装类(smc.h):

代码语言:javascript
复制
#ifndef SMC_H
#define SMC_H
#include "getinfo.h"

#ifdef __cplusplus
extern "C"
{
#endif
//void smc_destroy(ctestsmc *a);
char* smc_getMaximumSpeedCpu();
char* smc_getCoreNumbers();

#ifdef __cplusplus
}

#endif
#endif // SMC_H

smc.cpp:

代码语言:javascript
复制
#include "smc.h"

char *smc_getMaximumSpeedCpu()
{
   char* c = getMaximumSpeedCpu();
   return c;
}

char *smc_getCoreNumbers()
{
    char* c = getCoreNumbers();
    return c;
}

我用smc.cpp创建了一个共享库,现在我想在例如C代码中使用我的库。

我应该如何在不包括任何头文件的情况下做到这一点?每当我包含smc的头文件时,我的C代码就不知道我在getinfo.h中使用过的库,比如fstream

编辑:

信息.h:

代码语言:javascript
复制
#ifndef INFO_H
#define INFO_H
#include <stdlib.h>
#include <cstring>
#include <sys/statvfs.h>
#include <libssh/libssh.h>

class info
{
private:
    std::ifstream ifile;
    std::ofstream ofile;
    std::vector<std::string> lists;
    std::string str;
    ssh_session my_ssh_session ;

public:
    info();
    info(const void *ip, const char* pw, const void *hostName);
    ~info();
    std::string maximumSpeedCpu();
    std::string coreNumbers();
    const void* _hostName;
    const void* _ip;
    const char* _password;

info.cpp:

代码语言:javascript
复制
#include "info.h"
info::info(const void *ip, const char* pw, const void *hostName)
{
    int a;
    _ip = ip;
    _password = pw;
    _hostName = hostName;
    my_ssh_session = ssh_new();
}
info::info()
{
}
info::~info()
{
    ssh_disconnect(my_ssh_session);
    ssh_free(my_ssh_session);
}

std::string info::maximumSpeedCpu()
{
    //maximum speed of cpu
    getSSHState();
    std::string cpuSpeed;
    cpuSpeed = exec_ssh_command(my_ssh_session, "dmesg | grep 'MHz processor' | awk '{print $5}'" );
    return cpuSpeed;
}

std::string info::coreNumbers()
{
    //number of processors
    getSSHState();
    std::string coresNumber;
    coresNumber = exec_ssh_command(my_ssh_session, "cat /proc/cpuinfo | grep processor | wc -l");
    return coresNumber;
}
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2020-08-03 14:58:15

理论

您只能从C世界访问用C编写的函数,无论何时从C调用C++代码,都必须通过包装函数,在您的例子中是smc_*函数。

现在,注意包装函数的声明,它位于包装器的头文件smc.h中,不需要包含getinfo.hpp。这是关键的洞察力。包装器的头只告诉包含它的任何C程序、参数的类型和smc_*函数的返回值。标题必须坚持C。

例如,请参见下面的图像。foobar函数在只包含其他C头的wrapper.h文件中声明。wrapper.cpp文件实际上实现了包装器,并使用了来自C++世界的其他东西(如STL或其他类),其中包括它需要的C++头。

在您的例子中,smc.cpp将包括getinfo.hpp,而不是smc.h

但是,这些包装器函数的定义需要知道它正在包装的C++函数的类型。因此,smc.cpp将包括getinfo.h。此外,由于该文件将由C++编译器编译,因此它将理解包含的标头中对C++ STL的任何引用。

编辑:代码示例

假设我想包装class cppworld

cppworld.hpp

代码语言:javascript
复制
class cppworld {
public:
    cppworld();
    int one();
};

cppworld.cpp

代码语言:javascript
复制
#include <iostream>
#include "cppworld.hpp"

cppworld::cppworld() {}

int cppworld::one() {
    return 1;
}

我用wrapper.hwrapper.cpp编写了一个包装器。

wrapper.h

代码语言:javascript
复制
#ifdef __cplusplus
extern "C"
{
#endif

int get_one();

#ifdef __cplusplus
}
#endif

wrapper.cpp

代码语言:javascript
复制
#include "wrapper.h"
#include "cppworld.hpp"

int get_one() {
    cppworld obj = cppworld();

    return obj.one();
}

我可以将wrapper.cppcppworld.cpp编译成一个共享库。然后,为了使用C库,我创建了下面的C程序。

cworld.c

代码语言:javascript
复制
#include <stdio.h>
#include "wrapper.h"

int main() {
    printf("Calling one() returns: %d\n", get_one());
}
票数 2
EN

Stack Overflow用户

发布于 2020-08-03 18:48:13

每当我包含smc的头文件时,我的C代码就不知道我在getinfo.h中使用过的库,比如fstream。

是的,您需要为C提供所需函数的声明(而不是定义),而这些声明不能(直接)使用C++特性。

例如,您不能给C提供引用、模板或重载函数之类的东西。您也不能像std::string那样直接使用任意类对象,但是可以将它们作为不透明的指针传递,因为对于C它们只是指针。

不管你是怎么做的,你都需要C只看到表面上的C函数。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/63230462

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档