Solved

handling byte array in c++

Posted on 2002-07-21
9
724 Views
Last Modified: 2013-12-14
I have a c++ dll (pure c++, no MFC support) which is called by a vb program. vb program creates,populates and passes a user-defined structure to the c++ dll. The dll acts on this data, in turn populates some more values in the structure and returns it to vb. The user-defined structure is very large (atleast 40000bytes) and has many sub structures, strings, arrays. On compilation of vb this is giving me a "Too many local, non-static variables" error. MSDN says this is a vb bug and information should be passed as a byte array and gives an example of how this is to be done. Now my problem is receiving this byte array, extracting data from it so that it populates the corresponding structure on c++ side, and returning it again as a byte array. Hitherto I have used CByteArray which did most of the work for me. But how to do it in pure c++? Experts please advise.
0
Comment
Question by:aparna-learner
9 Comments
 
LVL 22

Expert Comment

by:ambience
ID: 7169101
what is the prototype of your C++ functions, that are called from VB, i.e. functions that are implementation of IDL methods.

can post some existing code, would help a lot to understand the structures and etc.
0
 

Author Comment

by:aparna-learner
ID: 7169322
The prototype of my c++ function that is exported is
void  __stdcall    MyProc(TDS& lpStruct)
where TDS is the structure. vb has got a structure corresponding to it. vb populates input values in the TDS and passes to MyProc. MyProc populates output values in same struct and returns to VB.
I get  "Fixed or static data can't be larger than 64K" compile time error.
0
 
LVL 30

Expert Comment

by:Axter
ID: 7169536
>>I have used CByteArray which did most of the work for
>>me. But how to do it in pure c++? Experts please advise.

You can use std::vector<char> to replace CByteArray
0
 
LVL 8

Expert Comment

by:fl0yd
ID: 7170106
Bytes are unsigned, so use

std::vector<unsigned char> byte_vec;

instead. Also, to reduce recurring re-allocation use

byte_vec.reserve( estimated_average_size_needed );

This estimate doesn't have to be exact, since the container will expand when the number of bytes exceeds byte_vec.capacity().
0
Find Ransomware Secrets With All-Source Analysis

Ransomware has become a major concern for organizations; its prevalence has grown due to past successes achieved by threat actors. While each ransomware variant is different, we’ve seen some common tactics and trends used among the authors of the malware.

 
LVL 22

Expert Comment

by:ambience
ID: 7170943
Say you have a function like

void  __stdcall    MyProc(TDS& lpStruct)
{
}

if you later change it so that it take a byte array as arugument

void  __stdcall    MyProc(BYTE* pArrr)
{

   // You can still typecast and use it like

   struct TDS* lpStruct = (struct TDS*)pArr;

   lpStruct->someField = 0;
}

this is going to work unless there are some issues related to the structure byte-alignment.

How are you passing the array from VB (i.e. converting the structure to Byte array and then passing it) ?
0
 

Author Comment

by:aparna-learner
ID: 7171005
WRT ambience's comment, I am passing the data from VB as follows:
Const UDT_SIZE = 50000
Dim tds As MYTDS
Dim ab() As Byte
ReDim ab(UDT_SIZE)
'populating tds
tds.s1="hello"
tds.s2="world"
'and so on
CopyMemory ab(0), tds, UDT_SIZE
MyProc ab(0)
CopyMemory tds, ab(0), UDT_SIZE

But there is a problem I am facing here. The copymemory works fine when all tds members are strings, but if structure includes integers and doubles, it is not getting populated correctly. But that is a vb issue I guess. For now I will pass all data as strings. My problem here is when ab(0) goes to c++ dll, how to extract these strings in the most optimum way? I have already tried the laborious memcpy() where I need to count characters of each string, etc. I want to know if there is another and more elegant way.
0
 
LVL 1

Expert Comment

by:ris
ID: 7174925
I don't know much about the VB side of it, but have you considered creating a class on the C++ side to encapsulate the conversion from a byte array to a structure?  Consider...

class CTDS
{
  CTDS(BYTE* pDataFromVBDLL);
  ...
  char* m_s1;
  char* m_s2;
  int m_nSomeInt;
  ...
};


CTDS::CTDS(BYTE* pDataFromVBDLL)
{
  BYTE* pCurrent = pDataFromVBDLL;

  //extract s1 from BYTE array
  strcpy(m_s1, (char*)pCurrent);
  pCurrent += strlen(m_s1) + 1; //+1 skips NULL terminator

  //extract s2
  strcpy(m_s2, (char*)pCurrent);
  pCurrent += strlen(m_s2) + 1;

  //extract int
  //NOTE: you need to know how much space in the array
  //was used by VB for an integer.  Is it 32-bit? 16?
  //if VB uses 32-bit ints when creating the byte array
  m_nSomeInt = *((DWORD*)pCurrent);
  pCurrent += sizeof(DWORD);

  //and so on...
}

void __stdcall MyProc(BYTE* pArr)
{
  CTDS MyStruct(pArr);
  ...
}


-----------

Not sure if that's as elegant as you were looking for, but I hope it's at least a small improvement over the method you were referring to by "laborious memcpy".  At least it's encapsulated nicely.
0
 
LVL 11

Expert Comment

by:griessh
ID: 7378348
Dear aparna-learner

I think you forgot this question. I will ask Community Support to close it unless you finalize it within 7 days. You can always request to keep this question open. But remember, experts can only help you if you provide feedback to their questions.
Unless there is objection or further activity,  I will suggest to

     "PAQ at zero points"

since nobody had a satisfying answer for you.

PLEASE DO NOT ACCEPT THIS COMMENT AS AN ANSWER!
======
Werner
0
 
LVL 6

Accepted Solution

by:
Mindphaser earned 0 total points
ID: 7419988
Points refunded and moved to PAQ

** Mindphaser - Community Support Moderator **
0

Featured Post

Free Trending Threat Insights Every Day

Enhance your security with threat intelligence from the web. Get trending threat insights on hackers, exploits, and suspicious IP addresses delivered to your inbox with our free Cyber Daily.

Join & Write a Comment

Article by: SunnyDark
This article's goal is to present you with an easy to use XML wrapper for C++ and also present some interesting techniques that you might use with MS C++. The reason I built this class is to ease the pain of using XML files with C++, since there is…
Many modern programming languages support the concept of a property -- a class member that combines characteristics of both a data member and a method.  These are sometimes called "smart fields" because you can add logic that is applied automaticall…
This tutorial covers a step-by-step guide to install VisualVM launcher in eclipse.
The viewer will learn how to user default arguments when defining functions. This method of defining functions will be contrasted with the non-default-argument of defining functions.

707 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

13 Experts available now in Live!

Get 1:1 Help Now