pras_gupta
asked on
passing structures from VC++/ MFC application to C# dll
What is the best way of passing information from a VC+MFC application which will be calling C# dll to pass information.. what should be efficient some kind of binary structure or XML .. please notethat the data size is huge
some tutorials about marshalling:
http://www.codeproject.com/csharp/marshalCPPclass.asp
http://www.codeproject.com/vb/net/Marshaling_Structures.asp
http://www.codeproject.com/csharp/marshalCPPclass.asp
http://www.codeproject.com/vb/net/Marshaling_Structures.asp
ASKER
Ok , i am using a bit similar approach now. I have two choices that either i pass an array of values to the C# component or call the class struct in c# component and populate that from the VC++. which way will be faster. Passing a array or populating a class struct in a loop in C#.
CClass:: RunXXX()
{
HRESULT hr = CoInitialize(NULL);
// create the interface pointer.
IManager pIRule(__uuidof(XXXBase));
//Call the method for populating input for processing
pIRule -> AddInputStructures( long m_lProductId,
long m_lFieldId,
long m_lFieldValue,
string m_strType,
bool m_bDisabled,
bool m_bEmpty,
bool m_bRequired);
pIRule ->GetOutPutVariables();
}
vs
i create and pass a array to the component
Passing array or class will have similar performance.
ASKER
I think i have make myself more clear now . Say I have a data of approximatly around 1000 numbers. I have two choices here.1
I loop thru all the 1000 values and populate a array in VC++ and pass it to the C# dll.
2. I loop thru 1000 values and populate the class in c# component and internally C# dll uses it. in this case i am making 1000 calls to the c# dll. like below code will be called 1000 times.
pIRule -> AddInputStructures( long m_lProductId,
long m_lFieldId,
long m_lFieldValue,
string m_strType,
bool m_bDisabled,
bool m_bEmpty,
bool m_bRequired);
pIRule ->GetOutPutVariables();
}
In this scenario what do you think will be faster.
I loop thru all the 1000 values and populate a array in VC++ and pass it to the C# dll.
2. I loop thru 1000 values and populate the class in c# component and internally C# dll uses it. in this case i am making 1000 calls to the c# dll. like below code will be called 1000 times.
pIRule -> AddInputStructures( long m_lProductId,
long m_lFieldId,
long m_lFieldValue,
string m_strType,
bool m_bDisabled,
bool m_bEmpty,
bool m_bRequired);
pIRule ->GetOutPutVariables();
}
In this scenario what do you think will be faster.
the 1000 calls will make your code significative slower than passing the entire array once.
ASKER
Thanks, what do you suggest is the best way to pass a array from VC++ to C# dll
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
I am doing this now is there a better way
double dFieldId[5] = { 111111, 222222, 333333, 444444, 555555 } ;
double dFieldValue[5] = { 100001, 200002, 300003, 400004, 500005 } ;
double dType[5] = { 0,1,0,1,0 } ;
double dDisabled[5] = { 1,0,1,0,1 } ;
// Create an global instance for ISplitArrayPtr Interface
ISplitArrayPtr objSplitArray ;
hr = objSplitArray.CreateInstance (__uuidof(CSplitArray)) ;
long m_Size = 5 ;
objSplitArray->InitializeArray(m_Size) ;
SAFEARRAY* sArrayId ;
SAFEARRAY* sArrayValue ;
SAFEARRAY* sArrayType;
SAFEARRAY* sArrayDisabled ;
SAFEARRAYBOUND sabounds[1];
sabounds[0].lLbound = 0;
sabounds[0].cElements = m_Size ;
sArrayId = SafeArrayCreate(VT_R8, 1, sabounds);
sArrayValue = SafeArrayCreate(VT_R8, 1, sabounds);
sArrayType = SafeArrayCreate(VT_R8, 1, sabounds);
sArrayDisabled = SafeArrayCreate(VT_R8, 1, sabounds);
//if ( *sArrayId == NULL || *sArrayValue == NULL || *sArrayType == NULL || *sArrayDisabled == NULL )
// return E_OUTOFMEMORY;
long lx[1] = {0L};
double dVal = 0 ;
for ( long lIndex = 0 ; lIndex < m_Size ; lIndex++ )
{
lx[0] = lIndex;
HRESULT hr1 ;
dVal = dFieldId[lIndex] ;
hr1 = ::SafeArrayPutElement(sArrayId, lx, &dVal);
dVal = dFieldValue[lIndex] ;
hr1 = ::SafeArrayPutElement(sArrayValue, lx, &dVal);
dVal = dType[lIndex] ;
hr1 = ::SafeArrayPutElement(sArrayType, lx, &dVal);
dVal = dDisabled[lIndex] ;
hr1 = ::SafeArrayPutElement(sArrayDisabled, lx, &dVal);
}
objSplitArray->PopulateFields( sArrayId, sArrayValue, sArrayType, sArrayDisabled ) ;
objSplitArray->DisplayFields() ;
XML will be 100% safe but will be bigger than binary.