void-pointer problem

Hey guys,

i got a question again :)

I am working with an C API wich i wanna encapsulate in C++ classes (It is about an OPC UA client, but that is minor matter).

Now i have to handle a union, which has only pointer-elements. To compiletime, i dont know on which pointer i have to access to.

So i have got the idea of a void pointer, which i can cast on the type of pointer i need.

Thats the code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
void* pArrayElement = 0;
        
switch (oNode.getDatatype())
{
  case OpcUaType_Boolean:
    pArrayElement = (OpcUa_Boolean*) pArrayElement;                   
    pArrayElement = pResults->Value.Value.Array.Value.BooleanArray;
    break;
  case OpcUaType_SByte:
    pArrayElement = (OpcUa_SByte*) pArrayElement;
    pArrayElement = pResults->Value.Value.Array.Value.SByteArray;
    break;
  case OpcUaType_Byte:
    pArrayElement = (OpcUa_Byte*) pArrayElement;
    pArrayElement = pResults->Value.Value.Array.Value.ByteArray;
    break;
  case OpcUaType_Int16:
    pArrayElement = (OpcUa_Int16*) pArrayElement;
    pArrayElement = pResults->Value.Value.Array.Value.Int16Array;
    break;
  case OpcUaType_UInt16:
    pArrayElement = (OpcUa_UInt16*) pArrayElement;
    pArrayElement = pResults->Value.Value.Array.Value.UInt16Array;
    break;
  case OpcUaType_Int32:
    pArrayElement = (OpcUa_Int32*) pArrayElement;
    pArrayElement = pResults->Value.Value.Array.Value.Int32Array;
    break;
  case OpcUaType_UInt32:
    pArrayElement = (OpcUa_UInt32*) pArrayElement;
    pArrayElement = pResults->Value.Value.Array.Value.UInt32Array;
    break;
  case OpcUaType_Int64:
    pArrayElement = (OpcUa_Int64*) pArrayElement;
    pArrayElement = pResults->Value.Value.Array.Value.Int64Array;
    break;
  case OpcUaType_UInt64:
    pArrayElement = (OpcUa_UInt64*) pArrayElement;
    pArrayElement = pResults->Value.Value.Array.Value.UInt64Array;
    break;

  default:
    oStatus.setLStatus(L_NODE_WRONGTYPE_GETVALUE);
    pArrayElement = (L_CHARACTER*)pArrayElement; 
}
        
if (pArrayElement != 0)
{
  for (uiIndex = 0; uiIndex < pResults->Value.Value.Array.Length; uiIndex++)
  {
    tValue.iValue.insert(uiIndex, *pArrayElement);   //<-Error
    pArrayElement++;
  }
}


oNode.getDatatype() returns an enum which has a couple more elements, than the few ones in the switch-construct.

There are the typedefs:

1
2
3
4
5
6
7
8
9
10
11
12
...
typedef int                 OpcUa_Int;
typedef unsigned int        OpcUa_UInt;
typedef void                OpcUa_Void;
typedef unsigned char       OpcUa_Boolean;
typedef char                OpcUa_SByte;
typedef unsigned char       OpcUa_Byte;
typedef short               OpcUa_Int16;
typedef unsigned short      OpcUa_UInt16;
typedef long                OpcUa_Int32;
typedef unsigned long       OpcUa_UInt32;
...


and

1
2
3
...
typedef char L_CHARACTER;
...


pResults->Value.Value.Array.Value is a union. Look at this:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
...
typedef union _OpcUa_VariantArrayUnion
{
    ...
    OpcUa_Boolean*           BooleanArray;
    OpcUa_SByte*             SByteArray;
    OpcUa_Byte*              ByteArray;
    OpcUa_Int16*             Int16Array;
    OpcUa_UInt16*            UInt16Array;
    OpcUa_Int32*             Int32Array;
    OpcUa_UInt32*            UInt32Array;
    OpcUa_Int64*             Int64Array;
    OpcUa_UInt64*            UInt64Array;
    ...
}
OpcUa_VariantArrayUnion;
...


tValue.iValue is an vector similar to the STL-Vector (not compatible), but i think that doesnt matter.

The Error occurs on the marked Line:
error C2100: illegal indirection


What can i do to implement the idea? Has i code the for-loop in each case with the respective pointer?
That would be not really elegant.

Thanks for your time.

Greetz from Germany
Last edited on
This pArrayElement = (OpcUa_Boolean*) pArrayElement; doesn't have any effect what so ever. pArrayElement is still void * and cannot be changed at runtime.

Put the switch inside the for loop. Instead of casting do the call directly:

1
2
  case OpcUaType_Boolean:
    tValue.iValue.insert(uiIndex, pResults->Value.Value.Array.Value.BooleanArray[uiIndex]);
Hmm...
I get an Array of unknown Size (when i am compiling). So i have to implement the for-loop in every case?
No, put the switch inside the for, like so:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
for (uiIndex = 0; uiIndex < pResults->Value.Value.Array.Length; uiIndex++)
{
  bool ok = false;
  switch (oNode.getDatatype())
  {
    case OpcUaType_Boolean:
      if(pResults->Value.Value.Array.Value.BooleanArray)
      {
          ok = true;
          tValue.iValue.insert(uiIndex, pResults->Value.Value.Array.Value.BooleanArray[uiIndex]);
      }
      break;
    case OpcUaType_SByte:
      if(pResults->Value.Value.Array.Value.SByteArray)
      {
          ok = true;
          tValue.iValue.insert(uiIndex, pResults->Value.Value.Array.Value.SByteArray[uiIndex]);
      }
      break;
...
  }
  if(!ok)
      break;
}


Having an union is generally not a good idea. It depends on the reason why, but usually there're better alternatives
Last edited on
Oh man,

thanks for the broad hint :D. Of course is that the solution.

Im really no friend of unions, but the C-API which i got requires it. So i have to handle it.
Topic archived. No new replies allowed.