3

Edit: Since my first post I have come up with a minimal working example. In the code that follows, how do I access the contents of $testvar? The relevant places are shown with <--- comments in the following code.

$a = array(1.1,2.2);
$b = array(6.6,7.7);
$testvar = new VARIANT($a,VT_ARRAY|VT_VARIANT);
$testvar[0] = new VARIANT($a,VT_ARRAY|VT_VARIANT);
$testvar[1] = new VARIANT($b,VT_ARRAY|VT_VARIANT);
print "Count: ".count($testvar)."<br />\n";
print "Variant type: ";
print variant_get_type($testvar);
print "<br />\n";
print "var_dump: ";
var_dump($testvar);
print "<br />\n";
//print $testvar[0]; // <- How do I access the elements of the VARIANT ?????
foreach($testvar as $val)
{
    print count($val);
    print "<br />\n";
    print $val[0];   // <- How do I access the elements of the VARIANT ?????
    print "<br />\n";
}

Note also that I am aware of this question and answer (How do you read from a multidimensional variant array returned from a COM object in PHP?) but unfortunately the solution there uses a 32-bit COM control and I am restricted to a 64-bit platform.

%%%%%%%%%%%%%%%%%% Original Post Follows %%%%%%%%%%%%%%%%%%%%%

I am calling a COM object from PHP, but am having trouble printing the contents of the returned variable when it is a VARIANT.

I'm starting with a very simple COM object that just adds two numbers together. The following code works fine, and displays the number 3:

$my_dll = new COM('write_data_type.Class1');
$my_dll->write_data_type(1, $outvar, 1.0, 2.0);
echo $outvar;

However, I cannot figure out how to work with Arrays of data. The following code works, in that it calls the COM method without throwing an error:

$a = Array(1.0,2.0);
print_r(array_values($a));

$b = Array(7.0,5.0);
print_r(array_values($b));

$my_dll = new COM('write_data_type.Class1');
$my_dll->write_data_type(1, $outvar, $a, $b);

However I can't figure out how to either access or display the value of $outvar.

If I use:

var_dump($outvar);

then the following is printed,

object(variant)#2 (0) { }

However I have no idea what that means. Is there any documentation describing what the #2, the (0) and the { } mean?

Not too surprisingly, the following fails with a message saying that the variable isn't an Array.

print_r(array_values($outvar));

Can anyone tell me how to display the contents of $outvar (or a VARIANT in general) and also extract its elements?

If it's useful, the prototype for the function being called is,

/* [helpstring][id] */ HRESULT ( STDMETHODCALLTYPE *write_data_type )( 
            IClass1 * This,
            /* [in] */ long nargout,
            /* [out][in] */ VARIANT *c,
            /* [in] */ VARIANT a,
            /* [in] */ VARIANT b);

Everything works fine when a and b are scalars. The problem I am having (as per the example data at the top of the question) is when a and b each contain more than 1 number.

EDIT: The output of

com_print_typeinfo($outvar);

is: (the formatting is mine)

class IClass1 { /* GUID={0FE9C130-58E3-4E35-BC23-11CF1280BB7D} */
/* DISPID=1610612736 */
function QueryInterface(
   /* VT_PTR [26] [in] --> ? [29] */ &$riid,
   /* VT_PTR [26] [out] --> VT_PTR [26] */ &$ppvObj ) { } /* DISPID=1610612737 */ /* VT_UI4 [19] */

function AddRef( ) { } /* DISPID=1610612738 */ /* VT_UI4 [19] */

function Release( ) { } /* DISPID=1610678272 */

function GetTypeInfoCount(
   /* VT_PTR [26] [out] --> VT_UINT [23] */ &$pctinfo ) { } /* DISPID=1610678273 */

function GetTypeInfo(
   /* VT_UINT [23] [in] */ $itinfo,
   /* VT_UI4 [19] [in] */ $lcid,
   /* VT_PTR [26] [out] --> VT_PTR [26] */ &$pptinfo ) { } /* DISPID=1610678274 */

function GetIDsOfNames(
   /* VT_PTR [26] [in] --> ? [29] */ &$riid,
   /* VT_PTR [26] [in] --> VT_PTR [26] */ &$rgszNames,
   /* VT_UINT [23] [in] */ $cNames,
   /* VT_UI4 [19] [in] */ $lcid,
   /* VT_PTR [26] [out] --> VT_I4 [3] */ &$rgdispid ) { } /* DISPID=1610678275 */

function Invoke(
   /* VT_I4 [3] [in] */ $dispidMember,
   /* VT_PTR [26] [in] --> ? [29] */ &$riid,
   /* VT_UI4 [19] [in] */ $lcid,
   /* VT_UI2 [18] [in] */ $wFlags,
   /* VT_PTR [26] [in] --> ? [29] */ &$pdispparams,
   /* VT_PTR [26] [out] --> VT_VARIANT [12] */ &$pvarResult,
   /* VT_PTR [26] [out] --> ? [29] */ &$pexcepinfo,
   /* VT_PTR [26] [out] --> VT_UINT [23] */ &$puArgErr ) { } /* DISPID=1 */ /* VT_PTR [26] */ /* property MWFlags */ var $MWFlags; /* DISPID=1 */ /* property MWFlags */ var $MWFlags; /* DISPID=2 */

function write_data_type(
   /* VT_I4 [3] [in] */ $nargout,
   /* VT_PTR [26] [in][out] --> VT_VARIANT [12] */&$c,
   /* VT_VARIANT [12] [in] */$a,
   /* VT_VARIANT [12] [in] */ $b){ /* Method write_data_type */ } /* DISPID=3 */

function MCRWaitForFigures( ) { /* Method MCRWaitForFigures */ } }
Phil Goddard
  • 10,571
  • 1
  • 16
  • 28
  • https://secure.php.net/manual/en/class.variant.php 2 is the type (VT_I2, 16-bit integer https://secure.php.net/manual/en/com.constants.php) and 0 is the value. C/C++ definition of the VARIANT on the native side is here: https://msdn.microsoft.com/en-us/library/e305240e-9e11-4006-98cc-26f4932d2118(VS.85) – Simon Mourier Mar 06 '18 at 06:01
  • Strange, as the method should be outputting a Variant containing the 2 decimal numbers 8.0 and 7.0. The very last line in the COM object dumps its return value (i.e. those 2 numbers) to file, so it thinks it's outputting the right thing. Why would PHP think it's getting an integer 0? I've also made an edit to the end of the question asking why `com_print_typeinfo` doesn't work. – Phil Goddard Mar 06 '18 at 17:46
  • `com_print_typeinfo` expects an object, not a VARIANT (a VARIANT can hold an object but it's not an object). Can you show how is your COM object `write_data_type` method defined and implemented? – Simon Mourier Mar 06 '18 at 17:53
  • I can't show the implementation, but have added the function prototype to the question. In this case the implementation is essentially to add corresponding elements in the input vectors to create an output vector. (It's pretty simple at this stage as I'm trying understand how to pass, and work with data using COM in PHP. My final implementation will be much more complex. – Phil Goddard Mar 06 '18 at 18:02
  • Can you add the output of `com_print_typeinfo($my_dll);` – Hackerman Mar 06 '18 at 18:23
  • @Hackerman, I've added the output to the end of the question. Note the DLL is autogenerated from another application, so there some bumph in there that's perhaps not typical. – Phil Goddard Mar 06 '18 at 18:52
  • How about to just `echo $outvar;` or `echo (string)$outvar;` – Hackerman Mar 06 '18 at 19:56
  • In both cases an error is thrown: ` Object of class variant could not be converted to string` – Phil Goddard Mar 06 '18 at 20:18

0 Answers0