我在C++中有一个类,我想利用它创建一个共享库,并使用C语言或其他语言。这是我想从它创建一个库的类:
getinfo.h
#ifndef GETINFO_H
#define GETINFO_H
#include "info.h"
char* getMaximumSpeedCpu();
char* getCoreNumbers();
#endifgetinfo.cpp:
#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):
#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_Hsmc.cpp:
#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:
#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:
#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;
}发布于 2020-08-03 14:58:15
理论
您只能从C世界访问用C编写的函数,无论何时从C调用C++代码,都必须通过包装函数,在您的例子中是smc_*函数。
现在,注意包装函数的声明,它位于包装器的头文件smc.h中,不需要包含getinfo.hpp。这是关键的洞察力。包装器的头只告诉包含它的任何C程序、参数的类型和smc_*函数的返回值。标题必须坚持C。
例如,请参见下面的图像。foo和bar函数在只包含其他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
class cppworld {
public:
cppworld();
int one();
};cppworld.cpp
#include <iostream>
#include "cppworld.hpp"
cppworld::cppworld() {}
int cppworld::one() {
return 1;
}我用wrapper.h和wrapper.cpp编写了一个包装器。
wrapper.h
#ifdef __cplusplus
extern "C"
{
#endif
int get_one();
#ifdef __cplusplus
}
#endifwrapper.cpp
#include "wrapper.h"
#include "cppworld.hpp"
int get_one() {
cppworld obj = cppworld();
return obj.one();
}我可以将wrapper.cpp和cppworld.cpp编译成一个共享库。然后,为了使用C库,我创建了下面的C程序。
cworld.c
#include <stdio.h>
#include "wrapper.h"
int main() {
printf("Calling one() returns: %d\n", get_one());
}发布于 2020-08-03 18:48:13
每当我包含smc的头文件时,我的C代码就不知道我在getinfo.h中使用过的库,比如fstream。
是的,您需要为C提供所需函数的声明(而不是定义),而这些声明不能(直接)使用C++特性。
例如,您不能给C提供引用、模板或重载函数之类的东西。您也不能像std::string那样直接使用任意类对象,但是可以将它们作为不透明的指针传递,因为对于C它们只是指针。
不管你是怎么做的,你都需要C只看到表面上的C函数。
https://stackoverflow.com/questions/63230462
复制相似问题