-2

A function written in C e.g.

extern "C" void cityManipulator( void * data, int size);

takes an array similar to this,

Shanghai, China, 17
Delhi, India, 16
Cairo, Egypt, 7

It then capitalizes the city names and multiplies the population number by a one million. The function works with the value that I pass not the copy.
The function requires to know the dimensions of the array: how many rows and columns and the size in bytes of each element ( i.e. each city name ) in a given column
I am not interested in how the C function works but I want to use it as is from C++.
The array has to be dynamic i.e. the columns and rows are not static.

How should my data structure that I need to pass to this function look like?

This is my attempt. Use a nested vector of boost::variant

typedef boost::variant<std::string, int> Var;
typedef std::vector<Var> OneRow;
std::vector<OneRow> theArray;

But I can't figure out how to pass theArray to cityManipulator( void *d ).
&theArray[0]
does not work.

BenMorel
  • 34,448
  • 50
  • 182
  • 322
kl_ostic
  • 1
  • 1
  • The requirement for "variable columns" is not clear to me. Do you mean that the strings should be resizeable? That'd be difficult. If the strings are of fixed length but variable content, then it should be easy enough. – Kerrek SB Sep 01 '11 at 19:47
  • @Kerrek SB Variable null terminated strings would be ideal but I can live with fixed strings if I had no better alternative. – kl_ostic Sep 01 '11 at 19:53

2 Answers2

1

I wouldn't even attempt to pass an instance of a class to C. My approach would be:

  1. export my data from my C++ classes into a memory suitable for the function to be called
  2. Call the function
  3. import the modified data back to my C++ classes.

Either that, or if the function is trivial, re-implement it in C++.


EDIT: Implementing variable number of elements in a structure in C.

If all you have is access to a single parameter, you cannot pas the number of elements in an array explcitly. In that case, there are two methods you can use.

The first method is flagging the last entry in some manner. The explicit way of doing this is to add a field isLastEntry in the structure, and set it to false in all entries, except the last one. The implicit way of doing it is to allocate a special element, and make it the last entry in the array. Zero terminated strings fall into this category. For complex structures, such as the one provided in npclaudiu's answer, you can add a final dummy field where all pointers are set to NULL as the terminator.

The alternative method is having a structure that contains the length as its first element, and the array as its last. Since C doesn't provide support for variable length arrays, you can use a trick such as the one asked in this question. Simply replace the BYTE type with your structure to handle complex types instead of strings.

Community
  • 1
  • 1
vhallac
  • 13,301
  • 3
  • 25
  • 36
  • 'memory suitable for the fucntion to be called' is really what my question is about. The example I provided is really contrived but the point is there are library API functions that have similar characteristics – kl_ostic Sep 01 '11 at 19:34
  • Ah, there is no way to know. It should be specified by the function's documentation, or source code if there is none. Once you know the layout, you can use struct and plain old arrays to construct memory matching what the function expects. – vhallac Sep 01 '11 at 19:48
  • The function requires to know the dimensions of the array: how many rows and columns and the size in bytes of each element ( i.e. each city name ) in a given column – kl_ostic Sep 01 '11 at 19:59
  • I thought your question was on a function that already existed. Are you asking how such a function can be written? – vhallac Sep 01 '11 at 20:02
  • The C function already exists and assume cannot be changed. I am trying to provide more information about its arguments – kl_ostic Sep 01 '11 at 20:05
  • If it exists, then the function contains the info you are after. There are a number of ways you can achieve the variable number of entries problem. I'll outline two such methods in my answer. – vhallac Sep 01 '11 at 20:18
0

You could also try this:

// C++

struct Row {
    char* City;
    char* Country;
    int Population;
};

std::vector<Row> rows;

// Then call your C function like this:
cityManipulator(&rows[0]);
npclaudiu
  • 2,401
  • 1
  • 18
  • 19