Passing byte array as variant from VC-ActiveX to VB will crash

I'm passing binary byte data as a variant from a VC++ OCX to a VB program during a fired event. The application is crashing.
Pls. see code below:
Environment VS 6.0 prof.
==========================================================

// The VB side:
Private Sub Tool4MActX1_OnControlMessageReceived(ClientID As Integer, _
                                                 MsgType As Integer, _
                                                 SourceDeviceID As Integer, _
                                                 InstanceID As Integer, _
                                                 FBlockID As Integer, _
                                                 FunctionID As Integer, _
                                                 OpType As Integer, _
                                                 TelegramID As Integer, _
                                                 Timestamp As Long, _
                                                 DataLength As Long, _
                                                 MsgData As Variant _
                                                )
Dim DataBytes As String
Dim idx As Integer


DataBytes = " "

DataBytes = "Control message RX " _
           + Hex(SourceDeviceID) _
           + "." _
           + Hex(InstanceID) _
           + "." _
           + Hex(FBlockID) _
           + "." _
           + Hex(FunctionID) _
           + "." _
           + Hex(TelegramID) _
           + " (" _
           + Hex(DataLength) _
           + ") "
For idx = 0 To DataLength - 1
   DataBytes = DataBytes + Hex(MsgData(idx))
   DataBytes = DataBytes + " "
Next idx

OutputText (DataBytes)

End Sub




// The VC++ side:
{
  SAFEARRAYBOUND sabound[1] ;
  SAFEARRAY      *psa ;
  VARIANT        varTemp ;

  P_MA_MESSAGE   pM = &iMsg ;
  long           DataLength = pM->Length ;

  short ClientID   = pM->ClientID ;
  short MsgType    = pM->Type ;
  short DeviceID   = pM->DeviceID ;
  short FBlockID   = pM->FBlockID ;
  short InstanceID = pM->InstID ;
  short FunctionID = pM->FunctionID ;
  short OpType     = pM->OpType ;
  short TelegramID = pM->TelID ;
  long  Timestamp  = pM->Timestamp.HighResCnt ;

  // Create safearray of unsigned char.
  sabound[0].cElements = DataLength ;
  sabound[0].lLbound   = 0 ;
  psa = SafeArrayCreate( VT_UI1, 1, sabound ) ;

  if( psa )
  {
     // Copy binary data into array    
     unsigned char *pc ;

     SafeArrayAccessData( psa, (void HUGEP*  FAR*)&pc ) ;
     memcpy( pc, pM->Data, pM->Length ) ;
     SafeArrayUnaccessData( psa ) ;

     varTemp.vt = VT_ARRAY | VT_UI1 ;
     varTemp.parray  = psa ;
  }
 
  // Fire the event (will crash with an acces violation
  FireOnControlMessageReceived( &ClientID,
                                &MsgType,
                                &DeviceID,
                                &FBlockID,
                                &InstanceID,
                                &FunctionID,
                                &OpType,
                                &TelegramID,
                                &Timestamp,
                                &DataLength,
                                &varTemp
                              ) ;


Calling FireOnControlMessageReceived will cause an
access violation in MSVBVM60.DLL!

Output from the disassemble window within VS:

660FEA36   adc         byte ptr [esi-1],ah
660FEA39   adc         dword ptr [eax],edx
660FEA3B   push        es
660FEA3D   adc         dl,byte ptr [eax]
660FEA3F   sub         ax,offset ProcCallEngine+19E4h (660fea41)
660FEA43   pop         ss
660FEA45   adc         dl,byte ptr [eax]
660FEA47   cmp         di,word ptr [ecx]
660FEA4A   adc         byte ptr [esi+56h],ah
660FEA4D   mov         esi,ecx
660FEA4F   mov         cx,word ptr [esi]   // crash because ESI is 0x00000050
optitasAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

rdrunnerCommented:
Try this when creating the array and passing it to the C OCX

dim a() as byte
a = StrConv(DataBytes, vbFromUnicode)
OutputText a

0
optitasAuthor Commented:
Just for clarification:
I'm not passing binary data (byte array) to the C++ OCX but to the VB part.
The problem is when calling the FireOnControlMessageReceived() function.
The "OutputText" function is a local funtion in the VB file and does not make any problems.
The problem must be somewhere in the declaration (and usage) of the variant varTemp which causes the VB6 dll to crash when transferring it to the VB part..
0
aquila98Commented:
maybe declaring
SAFEARRAY FAR* psa;

and replace
 SafeArrayAccessData( psa, (void HUGEP*  FAR*)&pc ) ;
 memcpy( pc, pM->Data, pM->Length ) ;
 SafeArrayUnaccessData( psa ) ;

 varTemp.vt = VT_ARRAY | VT_UI1 ;
 varTemp.parray  = psa ;

it is after all an array of byte that your are passing as a variant...
HRESULT hr;
long idx[ 1 ] ;
_variant_t vt;
for(i=0;i<pM->Length;i++)
{
   idx[0]= i;
   vt= _variant_t(pM->Data[i]);
   hr = SafeArrayPutElement(      psa ,      idx,  &vt ) ;
   assert(SUCCEEDED(hr));
}
VARIANT v ;
VariantInit(&v);

 v.parray = psa ;
 v.vt = VT_ARRAY | VT_VARIANT ;
 return v ;

...
0
Cloud Class® Course: Microsoft Office 2010

This course will introduce you to the interfaces and features of Microsoft Office 2010 Word, Excel, PowerPoint, Outlook, and Access. You will learn about the features that are shared between all products in the Office suite, as well as the new features that are product specific.

optitasAuthor Commented:
Does NOT work.
Application still crashing...
First of all now VB gives me an error when running in debug mode in function: Tool4MActX1_OnControlMessageReceived():
Runtime error '458'
Variabel uses an automation type not supported in VisualBasic

Here's the modified code of the C++ OCX (VB code left unchanged!):

void CTool4MActXCtrl::FireTestEvent()
{
  SAFEARRAYBOUND sabound[1] ;
  SAFEARRAY FAR  *psa ;

  P_MA_MESSAGE   pM = &iMsg ;
  long           DataLength = pM->Length ;

  short ClientID   = pM->ClientID ;
  short MsgType    = pM->Type ;
  short DeviceID   = pM->DeviceID ;
  short FBlockID   = pM->FBlockID ;
  short InstanceID = pM->InstID ;
  short FunctionID = pM->FunctionID ;
  short OpType     = pM->OpType ;
  short TelegramID = pM->TelID ;
  long  Timestamp  = pM->Timestamp.HighResCnt ;

  // Create safearray of unsigned char.
  sabound[0].cElements = DataLength ;
  sabound[0].lLbound   = 0 ;
  psa = SafeArrayCreate( VT_UI1, 1, sabound ) ;

  HRESULT hr ;
  long    i ;
  long    idx[ 1 ] ;
  _variant_t vt ;

  if( psa )
  {
    for( i=0; i < DataLength; i++ )
    {
      idx[0]= i ;
      vt = _variant_t( pM->Data[ i ] ) ;
      hr = SafeArrayPutElement( psa, idx, &vt ) ;
      ASSERT( SUCCEEDED( hr ) ) ;
    }
  }
 
  VARIANT v ;
  VariantInit( &v ) ;

  v.parray = psa ;
  v.vt     = VT_ARRAY | VT_VARIANT ;

  // Fire the event (will still crash with an acces violation)
  FireOnControlMessageReceived( &ClientID,
                                &MsgType,
                                &DeviceID,
                                &FBlockID,
                                &InstanceID,
                                &FunctionID,
                                &OpType,
                                &TelegramID,
                                &Timestamp,
                                &DataLength,
                                &v
                              ) ;
}
0
aquila98Commented:
Try to create the array thus:
SafeArrayCreate(      VT_VARIANT,      1 , saBound ) ;

that's the only difference I noticed...

On the VB side, which variable cause the 458 error?

Cheers

TGIF!
0
rdrunnerCommented:
Hello optitas,

Please dont use the feedback function oin this way (Asking/explaining a question). Its a permanent record for finished questions. Dont give someone a negative feedback just for misunderstanding your question. The feedback is a permanent record. Please consider removing the feedback you gave. As you can imagine I dont like negative feedback ;)

Thanks in advance

P.s. : Try changing the Variable to long this will return you the memory address of the String. Then use memcopy to copy the data in a predefined string with the same size or byte array. VB and C handle stings quite differently internally.
0
optitasAuthor Commented:
To the moderator of this question:
Could you pls. close the request.
I solved the problem by myself.
The problem was that in multithreaded application some tricky posting of windows-messages had to be used to ensure proper operation of firing events to the ActiveX control.
In addition to that, some mutexes had to be used to wait unitll the message has been handled by the ActiveX container.
All of the abive code was correct and worked fine if the above mentioned solution was added to the ActiveX code.
Thanks for all the support, but none of the posted comments did get enough into depth to find a solution.
0
moduloCommented:
PAQed with points refunded (500)

modulo
Community Support Moderator
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
System Programming

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.