0

I have a problem with passing dynamically allocated structures to a function and accessing it's content.

The program uses mex to pass data from Matlab to C++. I use Visual Studio.

The structure I define in a header in 'InOut.h'

#include <string>
#include <cstdint>
#include <cstdlib>

struct sObjects {
    std::string Type;
    float *Position;
};
typedef struct sObject sObject;

In the main function I than allocate the structure is in 'MainFcn_Mex.cpp'

#include "MainFcn_Mex.h"

// ...

// get number of Objects from Matlab
int N_Obj = mxGetNumberOfElements(prhs[1]);

sObjects *Objects = new sObjects[N_Obj]; 

for (int k=0; k<N_Obj; k++)  {

    // get the pointer pointer map
    pMap = mxGetField(prhs[1],k,"Type");
    Objects[k].Type = mxArrayToString(pMap);

    // get the pointer pointer map
    pMap = mxGetField(prhs[1],k,"Position");
    // setting pointer to the first Element
    Objects[k].Position = (float*)mxGetPr(pMap);

    mexPrintf("Objects(%d,1).Type:  %s \n", k+1, Objects[k].Type);
}

create_Objects(Objects, N_Obj);

The function create_Objects is in a differente file 'create_Objects.cpp' and included via 'MainFcn_Mex.h':

#include <stdio.h>
#include <direct.h>
#define _USE_MATH_DEFINES
#include "math.h"
#include <cmath>

#include "mex.h"
#include "matrix.h"

#include <cuda.h>  
#include <cuda_runtime.h>
#include "device_launch_parameters.h"

#include "InOut.h"

void create_Objects(sObjects *Objects, int N_Obj);

The content of 'create_Objects.cpp' so far is:

#define _USE_MATH_DEFINES
#include "math.h"
#include <cmath>
#include "InOut.h"
#include "mex.h"

void create_Objects(sObjects *Objects, int N_Obj)
{
    for (int k=0; k<N_Obj; k++)  {
        mexPrintf("Objects(%d,1).Type:  %s \n", k+1, Objects[k].Type);
    }
}

Visual Studio tells me:

"error C2676: binary '[' : 'sObjects' does not define this operator or a conversion to a type acceptable to the predefined operator"

Why can I access the data in the main function and not in seccondary functions?

How can I access a dynamically allocated structure in other functions, when its size isn't known at compile time?

Thanks a lot for your time!

Rendel
  • 9
  • 3
  • you're showing us only pieces of the code; for one, where do you have `Objects` defined? Also are `create_Objects` and `create_OpticsObjects` the same? please provide complete information, preferably with a minimal working code.. Currently the question is not very clear. – Amro Nov 07 '14 at 21:29
  • Sorry, I mixed things up reducing the code to the parts I thought they might be crucial ... I edited the orignal post above – Rendel Nov 08 '14 at 09:07
  • I found a compilable working solution which I don't understand. I´ll try to summarize: I created the structure like `sObjects *Objects = new sObjects[N_Obj];` ... with a pointer ... then I allocate the structure within the loop. It works if I pass Objects like `create_Objects(sObjects *Objects, int N_Obj);`. But it doesn't if I pass it via a reference & – Rendel Nov 08 '14 at 09:38
  • I'm not sure I'm understanding the problem here. Please post the code you're *actually* using along with the exact error message... – Amro Nov 09 '14 at 09:01

1 Answers1

0

It looks like you are trying to use struct directly as a typedef. Simply add typedef to your struct definition, will turn it into a type.

Like this:

... #include "mex.h"

typedef struct sObjects {
    std::string Type;
    float *Position;
};

(Otherwise you should use the full struct keyword as in void create_OpticsObjects(struct sObjects &Objects, int N_Obj).)

Your function prototypes don't need the extern qualifier.

You don't need extern unless you want globals variables. You seem to want simply global structs or types in your example, so extern is not required.

Using extern for globals

What you could be referring to is an instance of your object (or a pointer to your object), and that can be made global by using extern. as in this excerpt from the header file:

... #include "mex.h"

typedef struct sObjects {
    std::string Type;
    float *Position;
};

extern sObjects *pointerToOnesObjects;

Then in ONE source file, you need to declare the 'real' variable as in (this is good to initialise it here):

sObjects *pointerToOnesObjects = NULL;

With this method your variable pointerToOnesObjects is now available globally (in all your source files that use the same header file).

Grantly
  • 2,546
  • 2
  • 21
  • 31
  • Hope it has helped. Please mark the 'answer' accordingly :). – Grantly Nov 07 '14 at 20:49
  • sorry, I was to fast ... I got rid of the extern and I defined the structure with typdef 'struct sObjects { ...}; typedef struct sObject sObject;' but the error "error C2676: binary '[' : 'sObjects' does not define this operator" maintains ... I also tried passing it directly as 'void create_OpticsObjects(struct sObjects &Objects, int N_Obj);' – Rendel Nov 07 '14 at 20:58
  • Once you have used ´typedef struct´ AAAA, AAAA can be used by itself as it is now a 'type'. You will not need to use the struct keyword either in 'void create_OpticsObjects(struct sObjects &Objects, int N_Obj);' ... – Grantly Nov 07 '14 at 21:08
  • @Grantly: the OP is using C++, in which case the `typedef` of `struct` is not necessary (unlike in C): http://stackoverflow.com/q/612328/97160 – Amro Nov 07 '14 at 21:26
  • Thanks @Amro, you are right. However it can be good practice, to avoid confusion in some weird cases. – Grantly Nov 07 '14 at 22:03
  • @Grantly: IMO there is no confusion. You do the same when you specify C++ classes instead of structs, you don't prefix the type name with anything.. – Amro Nov 07 '14 at 22:10