开发者

How to pass a dynamic 2D array from C++ to C as void *

开发者 https://www.devze.com 2023-04-01 17:28 出处:网络
A function written in C e.g. extern \"C\" void cityManipulator( void * dat开发者_开发百科a, int size);

A function written in C e.g.

extern "C" void cityManipulator( void * dat开发者_开发百科a, 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.


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.


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]);
0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号