none
retrun array of string from com object to javascript RRS feed

  • Question

  • I have a com object that returns an array of strings.  The actual type is SafeArray(BSTR).  While debugging the javascript code in Visual Studio 2005 I see the returned type as "Arrary of String" so I think great javascript knows it an array but when I pass this to the VBArray constructor or try to access the object as an array I get an error.  Typeof says it's unknown.  I over came this problem in another project by return a Scripting Dictionary object instead of a array but I want to solve this the right way.  It seems if VS know it an array it should treat it as an array in javascript.  I is the propery way to approach this?
    Kenney
    Friday, December 30, 2011 4:20 PM

Answers

  • You can do it as Sheng said using the variant. Here is a code sample:

    	// prepare a safearray to return to javascript, fileVec is vector<wstring> contains wstring
    	// Define the array bound structure
    	CComSafeArrayBound bound[1]; //one dim array
    	bound[0].SetCount(fileVec.size());
    	bound[0].SetLowerBound(0);
    	CComSafeArray<VARIANT> safeArray(bound, 1);
    
    	auto iter = fileVec.begin();
    	size_t pos = 0;
    	while (iter != fileVec.end())
    	{
    		safeArray.SetAt(pos, variant_t((*iter).c_str()));
    		++iter;
    		++pos;
    	}
    
    	SAFEARRAY sa;
    	LPSAFEARRAY lpsa = &sa;
    	HRESULT h = safeArray.CopyTo(&lpsa);
    
    	_variant_t ret;
    	ret.vt = VT_ARRAY | VT_VARIANT;
    	ret.parray = lpsa;
    	*retVal = ret.Detach();
    

    Hope this helps

    • Marked as answer by KennethK Tuesday, January 3, 2012 3:10 PM
    Sunday, January 1, 2012 11:37 AM

All replies

  • Javascript does not have a safe array type, pack it in a variant and unpack it in script using the VBArray class, or create an array in script and pass to your data populating method.

    You can also create an automation object that implements the same intefaces (IUnknown, IDispatch and IDispatchEx) as the Javascript array but that needs a lot of COM code



    The following is signature, not part of post
    Please mark the post answered your question as the answer, and mark other helpful posts as helpful, so they will appear differently to other users who are visiting your thread for the same problem.
    Visual C++ MVP
    Friday, December 30, 2011 10:18 PM
  • You can do it as Sheng said using the variant. Here is a code sample:

    	// prepare a safearray to return to javascript, fileVec is vector<wstring> contains wstring
    	// Define the array bound structure
    	CComSafeArrayBound bound[1]; //one dim array
    	bound[0].SetCount(fileVec.size());
    	bound[0].SetLowerBound(0);
    	CComSafeArray<VARIANT> safeArray(bound, 1);
    
    	auto iter = fileVec.begin();
    	size_t pos = 0;
    	while (iter != fileVec.end())
    	{
    		safeArray.SetAt(pos, variant_t((*iter).c_str()));
    		++iter;
    		++pos;
    	}
    
    	SAFEARRAY sa;
    	LPSAFEARRAY lpsa = &sa;
    	HRESULT h = safeArray.CopyTo(&lpsa);
    
    	_variant_t ret;
    	ret.vt = VT_ARRAY | VT_VARIANT;
    	ret.parray = lpsa;
    	*retVal = ret.Detach();
    

    Hope this helps

    • Marked as answer by KennethK Tuesday, January 3, 2012 3:10 PM
    Sunday, January 1, 2012 11:37 AM
  • I should have guessed due to the nature of script engines that variants are the prefered types for marshalling data when interfacing com with script engines.  I had this issue before but couldn't remeber why it didn't work. 
    Kenney
    Tuesday, January 3, 2012 3:15 PM