Re: [Rcom-l] Passing a COM object pointer does not work in the new rcom package
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
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
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