【问题标题】:convert a cpp class(.cpp file) into a c structure (.c file)将 c++ 类(.cpp 文件)转换为结构(.c 文件)
【发布时间】:2016-12-07 12:59:29
【问题描述】:

我有一个名为 Coverage 的类。它有一些数据类型为字符串的变量和一些返回类型为字符串的函数。

该类在其他头文件中使用。我想将转换为C 结构。其他头文件正在使用函数中的类对象。我想更改类,而不必在其他头文件中进行更改。

如果函数是

string ABC(Coverage* coverage);

我的结构应该作为一个行为类;但无法在结构中创建函数,因为在 C 中不建议这样做。

class Coverage
{
    std::string country;
    std::string KpRuntimeDir();
    std::string CRtimeDir();
    std::string RtimeDir();
};

将类转换为,例如:

struct Coverage n{
    char country[];
    /* [...] */
};

【问题讨论】:

  • 为什么要这样做,代码在哪里?
  • 我想制作一个现有的cpp应用程序,一个c应用程序。这就是我需要代码的原因
  • 为什么要这样做?你可以使用conditional compilation
  • 条件编译??

标签: c++ c


【解决方案1】:

我想到的唯一方法是将类重写为结构(仅变量成员)并在结构之外定义函数(而不是方法)。但是,如果您同时拥有私有和公有方法,以及一些自定义的构造函数,那么这似乎毫无意义,您将永远无法获得相同的安全性和功能。

struct Coverage{
    char country[256];
    --------
    };

char* RtimeDir(Coverage* c);

但在这种情况下,它可能会被任何会导致运行时错误的指针调用。

【讨论】:

  • 我在课堂上有一个构造函数,安全不是问题。
  • 所以如果你有自己的构造函数,那么我会另外创建一些函数,比如 void init(Coverage* obj);像构造函数那样初始化特定对象。
  • 如果遵循这种方式,我必须在函数调用中进行更改,因为我的类函数不需要任何参数,但通过这种方式实现,我必须将结构对象作为参数传递
  • 在 C 中不可能以其他方式执行此操作。您写道,不建议在 C 中在结构中定义函数。错误的。这是禁止的。
  • @AnkitSrivastava 是的,这是 C 和 C++ 之间的主要区别之一。事实上,非静态 C++ 方法确实有一个隐藏的 first 属性,其中包含指向对象的指针。
【解决方案2】:

您应该声明一个extern "C" 结构并将Coverage 的实例转换为一个:

extern "C" {
    struct CoverageAsACStruct
    {
        char country[SOME_DEFINED_CONSTANT_COUNTRY];
        char KpRuntimeDir[SOME_DEFINED_CONSTANT_RUNTDIR];
        char CRtimeDir[SOME_DEFINED_CONSTANT_CRTIMEDIR];
        char RtimeDir[SOME_DEFINED_CONSTANT_RTIMEDIR];
    };
}

class Coverage
{
    std::string country();
    std::string KpRuntimeDir();
    std::string CRtimeDir();
    std::string RtimeDir();
    void buildCStructure( struct CoverageAsACStruct* dst ) const;
};

void Coverage::buildCStructure( struct CoverageAsACStruct* dst ) const
{
    std::string cached_country = country();
    if (cached_country.size()+1 > sizeof(dst->country))
        // error?
    // same for other fields

    ::strcpy(dst->country, cached_country.c_str());
    // same for other fields
}

当您需要将Coverage 实例(我们称之为cov)传递给C 函数f() 时,传递它:

struct CoverageAsACStruct ccov;
cov.buildCStructure(&ccov);
f(&ccov);

您甚至可以将其嵌入到 Coverage 的成员函数中。

【讨论】:

  • 它会用 gcc 作为纯 C 代码编译吗?你不会得到一个错误:未知类型名称'class'吗?
  • @Lukasz 那时我可能误解了这个问题。我认为这完全是关于在 C++ 上下文中调用 C 代码。不是吗?
  • 我不是母语人士,所以我可能无法解密您的问题@AnkitSrivastava。
【解决方案3】:

我也不确定你为什么要这样做,但你也可以通过函数指针来做(但更喜欢条件编译),毕竟 C++ 是用 C 实现的。 在下面的代码中,我尝试通过使用函数指针将函数添加到 C 结构中来模拟 C 中的 C++ 结构。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

/*
class Someclass{
 string some_str;
public:
 string get();
 void set(string str);
};
*/
struct SomeStruct;
typedef char *(*Getter)(struct SomeStruct *);
typedef void (*Setter)(struct SomeStruct *, char *);
typedef void (*Initialize)(struct SomeStruct *);

typedef struct SomeStruct{
  char some_chr[1024];
  Getter get;
  Setter set;
  Initialize init;
}STR;

char * Get(STR *SStr){
  return SStr->some_chr;
}
void Set(STR *SStr, char *str){
  strncpy(SStr->some_chr,str,strlen(str)+1);
}
void Init(STR *STRstr){
  STRstr->get = Get;
  STRstr->set = Set;
}

int main(){

  STR SStr,Next_str;
  SStr.init = Init;
  SStr.init(&SStr);

  SStr.set(&SStr,"Example");
  printf("%s\n",SStr.get(&SStr));

  Next_str.init = Init;
  Next_str.init(&Next_str);

  Next_str.set(&Next_str,"Next_Example");
  printf("%s\n",Next_str.get(&SStr));

  return 0;
}

【讨论】:

  • 我认为这不是一个好的解决方案,因为它仅适用于 SomeStruct 的一个特定实例(恰好适用于 SStr)。肯定会给以后的开发或者扩展代码带来麻烦。
  • 是的,我将它设为全局,但也可以在本地实现,以使其适用于多个实例。我只是想表明它可以通过函数指针来完成,仅此而已。并且可以按照自己的方式实现它
  • 你的意思是,在 get/set 函数中定义对象?我真的不明白
  • 我更新了代码,看看,这又不是一个优雅的方法。请让我知道你的看法
  • 我不知道条件编译对我有什么帮助
猜你喜欢
  • 2011-12-25
  • 1970-01-01
  • 2016-09-10
  • 2016-01-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-11-12
  • 2010-10-10
相关资源
最近更新 更多