-3

I have a class named Coverage.It has some variables of datatype string and some functions with return type string.

This class is used in other header files.I want to convert the class into a C Structure. Other header file are using the class objects in there functions.I want to change the class in away that I don't have to make changes in other header files.

Like if the function were

string ABC(Coverage* coverage);

My structure should work as a class in behaviour; but unable to create a function in a structure as it is not recommended in C.

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

Convert the class as, for instance:

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

3 Answers3

3

The only way that comes to my mind is to rewrite the class as the structure (only variable members) and define function (instead of methods) outside the structure. But if you have both private and public methods, some seld-defined constructor, then it seems pointless and you will never get the same safeness and functionality.

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

char* RtimeDir(Coverage* c);

But in this case it may be invoked with any pointer that is casted which will leads to runtime errors.

Lukasz
  • 248
  • 1
  • 7
  • I do have a constructer in class and the security is not an issue. – Ankit Srivastava Dec 06 '16 at 10:46
  • 2
    so if you have own constructor then I would create additionally some function like void init(Coverage* obj); that initialize specific object as constructor does. – Lukasz Dec 06 '16 at 10:48
  • If a follow this way i have to make changes in the function calls because my class functions do not need any argument but by implementing this way I have to pass Structure object as an argument – Ankit Srivastava Dec 06 '16 at 10:49
  • 1
    There is no possibility to do it in other way in C. You wrote that defining function in structure in C is not recommended. Wrong. It is forbidden. – Lukasz Dec 06 '16 at 10:51
  • @AnkitSrivastava Yes, that’s one of the main differences between C and C++. In fact, non-static C++ methods do have a hidden first attribute containing a pointer to the object. – Melebius Dec 06 '16 at 13:59
2

You should declare an extern "C" structure and transform an instance of Coverage into one:

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
}

Whenever you need to pass a Coverage instance (lets call it cov) to a C function f(), pass it:

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

You could even embed this into a member function of Coverage.

YSC
  • 38,212
  • 9
  • 96
  • 149
  • 1
    Will it compile with gcc as pure C code ?? Won't you get an error: unknown type name ‘class’ ? – Lukasz Dec 06 '16 at 11:01
  • @Lukasz I might have misanderstood the question then. I though it was all about calling C code within a C++ context. Is it not? – YSC Dec 06 '16 at 13:45
  • I'm not a native speaker so I may have failed to decrypt your question @AnkitSrivastava. – YSC Dec 06 '16 at 13:49
2

I am also not sure why you want to do it, but you can also do it by Function Pointers (but prefer conditional compilation), after all C++ is implemented in C. In the below code I have tried to do that, emulate a C++ Structure in C, by adding Functions to a C structure by using Function Pointers.

#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;
}
D Untouchable
  • 332
  • 4
  • 9
  • I think it is not good solution because works only for one specific instance of SomeStruct (precisely for SStr). Surely it will make a trouble in future development or extending the code. – Lukasz Dec 06 '16 at 11:12
  • yeah, I made it global, but can also be implemented locally, to make it for multiple instances. I only wanted to show that it can be done via Function Pointers, thats all. And one can implement it in their way – D Untouchable Dec 06 '16 at 11:15
  • Do you mean, define object inside get/set function ? I don't really get it – Lukasz Dec 06 '16 at 11:20
  • 1
    I updated the code, just have a look, again it is not an elegant way to do it. Please do let me know your views – D Untouchable Dec 06 '16 at 11:44
  • I dont get an idea what help will conditional compilation make in my case – Ankit Srivastava Dec 06 '16 at 12:02
  • Now I see your point D Untouchable, I think it is good workaround to get rid of member function in favor of function pointer. Anyway, the code owner needs to be careful to pass appropriate object type to the function, but this is C :) But I wonder if we gain anything with this purpose if we compare it to my solution where function was declared outside the struct and no fnc pointer declared? You assign to function pointer always the same functions in this case, so I don't see any diffrence. – Lukasz Dec 06 '16 at 12:05
  • Hmm yours look like all c++ "string", so i don't think you can do much, they are different from C style strings. And are Function pointers any help to you? – D Untouchable Dec 06 '16 at 12:08
  • Not mine but Ankit's :D – Lukasz Dec 06 '16 at 12:10
  • I can't understand about the getter and setter datatype I can't use that class type in c – Ankit Srivastava Dec 06 '16 at 12:18
  • Ankit Getter/Setter are methods of the class. It i just an example to use Function Pointers. I will say unless you want to work on very low level for performance, there is no need for you to go for C, it is a futile effort. And if you badly want it in C then Best of Luck for the tough road ahead. – D Untouchable Dec 06 '16 at 12:23
  • It is very much needed to make the application in c. – Ankit Srivastava Dec 06 '16 at 12:58
  • Lukasz, the only difference that you have already pointed out, is type safety. With this solution, one will reduce the run time issues that you mentioned, the errors can be caught at compile time. And what I have tried is to emulate c++ Structure – D Untouchable Dec 06 '16 at 22:20