Re: [Rcom-l] Passing a COM object pointer does not work in the new rcom package

2008-10-29 Thread Thomas Baier

Dear Vilmos,

thanks for your mails and the very good analyses of the problem(s).

I've prepared a version of rscproxy including fixes for both problems. 
The new version of rscproxy should be available from CRAN soon.


The following code (slightly changed your code) now works:

  XL<-comGetObject("excel.application")
  a<-XL[["activecell"]]
  b<-a[["offset",3,3]]
  XL[["range",a,b]]<-matrix(1:16,a[["value"]],b[["value"]])

And the date/time code works, too:

  XL<-comGetObject("excel.application")
  a<-XL[["activecell"]]
  a[["value"]]

Thanks again,
Thomas

Prokaj Vilmos schrieb:

Dear Thomas,

I think I finally catched the bug. In the bdx_com.c file in the
BDXScalar2Variant function the BDX_HANDLE case was handled in the 
following way:


case BDX_HANDLE:
  {
LPSTREAM lStream = pBDXData->data.raw_data[0].ptr;
void* lTmpPtr = (void*) V_DISPATCH(pVariantData);
HRESULT lRc = CoUnmarshalInterface(lStream,&IID_IDispatch,
   &lTmpPtr);
//the problem is here ^
//lTmpPtr first receives the value of V_DISPATCH(pvariantData),
// which is NULL, then this is overwritten with the required ptr,
// however V_DISPATCH(pvariantData) remains untouched,
if(FAILED(lRc)) {
  BDX_ERR(printf("unmarshalling stream ptr %08x failed with hr=%08x\n",
 lStream,lRc));
  return -1;
} else {
  BDX_ERR(printf("successfully marshalled COM interface\n"));
// to see that this is really the problem change this line to
//   BDX_ERR(printf("successfully marshalled COM interface (%p %p)\n",
//   lTmpPtr,V_DISPATCH(pvariantData)));
}

/* create SEXP for COM object */
V_VT(pVariantData) = VT_DISPATCH;
break;
  }
A simple soultion is not to use a temporary pointer like below
case BDX_HANDLE:
  {
LPSTREAM lStream = pBDXData->data.raw_data[0].ptr;
//void* lTmpPtr;
HRESULT lRc = CoUnmarshalInterface(lStream,&IID_IDispatch,
   (void *) &V_DISPATCH(pVariantData));
if(FAILED(lRc)) {
  BDX_ERR(printf("unmarshalling stream ptr %08x failed with hr=%08x\n",
 lStream,lRc));
  return -1;
} else {
// Or copy the received value to the variant data structure like the
// commented line here
//V_DISPATCH(pVariantData)=lTmpPtr ;
BDX_ERR(printf("successfully marshalled COM interface (%p) \n",
   //lTmpPtr,
   V_DISPATCH(pVariantData)));
}

/* create SEXP for COM object */
V_VT(pVariantData) = VT_DISPATCH;
break;
  }

With either modification the reported problems disappear.

Best wishes
 Vilmos




___
Rcom-l mailing list
Rcom-l@mailman.csd.univie.ac.at
http://mailman.csd.univie.ac.at/mailman/listinfo/rcom-l
More information (including a Wiki) at http://rcom.univie.ac.at


[Rcom-l] Passing a COM object pointer does not work in the new rcom package

2008-10-29 Thread Prokaj Vilmos

Dear Thomas,

I think I finally catched the bug. In the bdx_com.c file in the
BDXScalar2Variant function the BDX_HANDLE case was handled in the 
following way:


case BDX_HANDLE:
  {
LPSTREAM lStream = pBDXData->data.raw_data[0].ptr;
void* lTmpPtr = (void*) V_DISPATCH(pVariantData);
HRESULT lRc = CoUnmarshalInterface(lStream,&IID_IDispatch,
   &lTmpPtr);
//  the problem is here ^
//  lTmpPtr first receives the value of V_DISPATCH(pvariantData),
// which is NULL, then this is overwritten with the required ptr,
// however V_DISPATCH(pvariantData) remains untouched,
if(FAILED(lRc)) {
  BDX_ERR(printf("unmarshalling stream ptr %08x failed with hr=%08x\n",
 lStream,lRc));
  return -1;
} else {
  BDX_ERR(printf("successfully marshalled COM interface\n"));
// to see that this is really the problem change this line to
//   BDX_ERR(printf("successfully marshalled COM interface (%p %p)\n",
//   lTmpPtr,V_DISPATCH(pvariantData)));
}

/* create SEXP for COM object */
V_VT(pVariantData) = VT_DISPATCH;
break;
  }
A simple soultion is not to use a temporary pointer like below
case BDX_HANDLE:
  {
LPSTREAM lStream = pBDXData->data.raw_data[0].ptr;
//void* lTmpPtr;
HRESULT lRc = CoUnmarshalInterface(lStream,&IID_IDispatch,
   (void *) &V_DISPATCH(pVariantData));
if(FAILED(lRc)) {
  BDX_ERR(printf("unmarshalling stream ptr %08x failed with hr=%08x\n",
 lStream,lRc));
  return -1;
} else {
// Or copy the received value to the variant data structure like the
// commented line here
//  V_DISPATCH(pVariantData)=lTmpPtr ;
BDX_ERR(printf("successfully marshalled COM interface (%p) \n",
   //lTmpPtr,
   V_DISPATCH(pVariantData)));
}

/* create SEXP for COM object */
V_VT(pVariantData) = VT_DISPATCH;
break;
  }

With either modification the reported problems disappear.

Best wishes
 Vilmos

--
Vilmos Prokaj
Eötvös Loránd University,
Department of Probability and Statistics
Pázmány Péter sétány 1/C
Budapest, 1117
Hungary

e-mail:[EMAIL PROTECTED]


___
Rcom-l mailing list
Rcom-l@mailman.csd.univie.ac.at
http://mailman.csd.univie.ac.at/mailman/listinfo/rcom-l
More information (including a Wiki) at http://rcom.univie.ac.at


[Rcom-l] Passing a COM object pointer does not work in the new rcom package

2008-10-28 Thread Prokaj Vilmos

Dear Thomas,

I switched to R-2.8.0, and I had to realize as others also reported in 
this mailing list, that under R-2.8.0 the rcom package does not work 
properly.  My concrete problem was that the following code (a similar to 
that one) caused a crash of R.


XL<-comGetObject("excel.application")
a<-XL[["activecell"]]
b<-a[["offset",3,3]]
XL[["range",a,b]]<-matrix(1:16,a,b)

It turned out that the result of XL[["range",a,b]] is NULL, and 
debugview showed the error code

com_property_get: error 80020009 getting property "range".

I started look for the problem, and I realized that the way of passing 
COMObject pointers has changed. Fortunately in the util.c file one can 
find the previous version of the  code. This does not compile for  2.8.0 
because the allocString  function is not available  in  this version. 
This can be corrected easily and with this version the  above code as 
well as the following one reported by

Christian Asseburg works properly.

library(rcom)
E<-comCreateObject("Excel.Application")
W1<-E[["Workbooks"]]$Add()
S1<-E[["ActiveSheet"]]
W2<-E[["Workbooks"]]$Add()
S1$Copy(Before=W2[["Worksheets",1]])


May I propose that until the problem with COMObject
pointers is solved the official version include the previous version 
of SEXP2Variant and Variant2SEXP functions. To save your time the modified 
version of util.c is attached. The only changes are 
#if 0 instead of #if 1

and all allocString is replaced with the appropriate mkChar call.

I minor problem with the Makevars file of rcom. It sets the 
PKG_LIBS flag, however it does not set


PKG_CPPFLAGS:=-I"$(RSCPROXY_DIR:%libs=%include)"

to find the include files from the installed rscproxy package.
Best wishes
Vilmos 


--
Vilmos Prokaj
Eötvös Loránd University,
Department of Probability and Statistics
Pázmány Péter sétány 1/C
Budapest, 1117
Hungary

e-mail:[EMAIL PROTECTED] 

/***
 *  RCOM : COM Client and Server for R
 *  Copyright (C) 2003-2005 Thomas Baier
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *
 *  ---
 *
 *  $Id: SC_proxy.h,v 1.6 2003/09/13 15:14:09 murdoch Exp $
 *
 **/

#include 
#include 
#include "rcom.h"
#include "bdx.h"
#include "bdx_util.h"
#include "bdx_com.h"
#include "bdx_SEXP.h"

/** get the CLSID from an ANSI string (prod id or clsid string) */
/*
** 07-07-30 | baier | now (char const*) instead of (char*)
*/
HRESULT com_getCLSID(char const* str,LPCLSID pclsid)
{
  HRESULT hr;
  OLECHAR* _pclsid;

  _pclsid = com_getOLECHAR (str);
  hr = CLSIDFromProgID(_pclsid,pclsid);
  free(_pclsid);
  return hr;
}

/* 1 helyett 0 */
#if 0
/** create a VARIANT from an SEXP */
BOOL SEXP2Variant(SEXP sexp,VARIANT* variant)
{
  BDX_Data* lBdx = NULL;
  int lRc;

  assert (variant != NULL);
  /* create a BDX structure from the SEXP */
  /*  RCOM_TRACE(printf("SEXP2Variant: calling SEXP2BDX\n")); */
  lRc = SEXP2BDX(sexp,&lBdx);

  if(lRc != 0) {
RCOM_TRACE(printf("conversion of SEXP to BDX failed with error %d\n",
  lRc));
  }

  /* convert the BDX structure to VARIANT */
  /*  RCOM_TRACE(printf("SEXP2Variant: calling BDX2Variant\n")); */
  lRc = BDX2Variant(lBdx,variant);
  /*  RCOM_TRACE(printf("SEXP2Variant: calling bdx_free\n")); */
  bdx_free(lBdx);

  if(lRc == 0) {
return TRUE;
  }
  RCOM_TRACE(printf("conversion from BDX to VARIANT failed with error %d\n",
lRc));
  return FALSE;
}
/** create an SEXP from a VARIANT */
BOOL Variant2SEXP(VARIANT* variant,SEXP* sexp)
{
  BDX_Data* lBdx;
  int lRc;

  assert(sexp != NULL);
  assert(variant != NULL);

  /* create a BDX structure from the VARIANT */
  lRc = Variant2BDX(*variant,&lBdx);

  if(lRc != 0) {
RCOM_TRACE(printf("conversion of VARIANT to BDX failed with error %d\n",
  lRc));
*sexp = NULL;
return FALSE;
  }

  /* convert the BDX structure to SEXP */
  lRc = BDX2SEXP(lBdx,sexp);
  bdx_free(lBdx);

  if(lRc != 0) {
*sexp = NULL;
return FALSE;
  }
  return TRUE;
}
#else
/** create a VARIANT from an SEXP */
BOOL SEXP2Variant(SEXP sexp,VARIANT* variant)
{
  assert (variant != NULL);

  /*
   * we