CIsForCookies
CIsForCookies

Reputation: 12837

declaring a vector-using function within extern "C"{}

I have one file (FILE_A.cpp) with a function's body as follows:

vector<char *> lines_vector;
foo(my_file_path, "zzz", lines_vector, fout);

foo is defined in another file (FILE_B.cpp):

void foo(char * in_file, char * keyword, vector<char *>& lines_vector, FILE * fout)

Since FILE_A.cpp uses FILE_B.cpp's function, it includes its headed, and here's the problem:

FILE_B.h has all of its function headers inside a

#ifdef __cplusplus
extern "C" {
#endif
...
void foo(char * in_file, char * keyword, vector<char *>& lines_vector, FILE * fout)
...
#ifdef __cplusplus
};
#endif

and when trying to add my function it doesn't recognize the vector. The errors given are

1) expected ',' or '...' before '<' token

2) expected initializer before '}' token

3) 'vector' has not been declared

which makes me suspect that extern C can't parse this. Is there a problem in using cpp objects inside extern "C" {} or is there another problem here?

Upvotes: 4

Views: 3422

Answers (3)

Jean-Fran&#231;ois Fabre
Jean-Fran&#231;ois Fabre

Reputation: 140256

the problem is: you cannot use C++ objects in C interfaces. How would do create such an object from the C side then?

So you have to change your call to:

void foo(char * in_file, char * keyword, char **lines_vector, int, lines_vector_size, FILE * fout)

then as you cannot map a vector to a buffer (How to cheaply assign C-style array to std::vector?), so to use a vector you'd need to create a vector<char *> work object and copy the data (only the pointers should be ok), work with it in your algorithm, then copy the vector data back to lines_vector (or if the pointers didn't change, just do nothing)

untested, I'd do naively as follows

void foo(char * in_file, char * keyword, char **lines_array, int, lines_array_size, FILE * fout)
{
     std::vector<char *> lines_vector;
     for (int i=0;i<lines_array_size;i++)
     {
        lines_vector.push_back(lines_array[i]);
     }

}

If the pointers themselves have been updated, you have to free the old ones and copy the new ones to the C structure. I'm not sure of what is the context, but this aspect is touchy (who's responsible for the allocated memory of each string...)

Upvotes: 5

Hatted Rooster
Hatted Rooster

Reputation: 36503

C doesn't know about templates.

std::vector<> is a class template.

It is thus impossible to use class templates while requesting for C-like linking with extern "C" since it can't distinguish std::vector<int> from std::vector<char> inside the linker without using name mangling.

Upvotes: 4

srdjan.veljkovic
srdjan.veljkovic

Reputation: 2548

Declarations inside extern "C" need to be plain C, not C++. IANALL, can't say what's "the law" by the C++ standard, but, some compilers will report an error (and they should), some a warning and some will just "go on", but, it's next to impossible to make this work, since std::vector<> is a template.

Upvotes: 8

Related Questions