Beim Compilieren keine Fehler. Excel stürzt aber ab.



  • Hi,
    Ich habe versucht eine Funktion für Excel zu schreiben (Als Prototyp habe ich den Interpolation-Addin genommen.).
    Der Versuch ist halbwegs gelungen, die Zahlen werden zurückgegeben, Excel stürzt aber gleich ab.

    Vermutlich habe was mit der Speicherfreigabe falsch gemacht.

    __declspec(dllexport) LPXLOPER MatCovar( LPXLOPER xArray )
    {
       static XLOPER	resultBuffer[dimResult];	// Return Data Array
    
       LPXLOPER	xPtr;	// pointers to arrays of x table data
    
       static XLOPER	xMulti;	// xArray coerced to xltypeMulti
    
       short		hasXMulti = 0,  // flags to indicate memory has been allocated
    		        error = -1;   // -1 if no error; error code otherwise
    
       ULONG		i, j, k,          // temporary index values
                    xSizeC, xSizeR,	// number of columns and rows	
        		    xCount = 0;
    
       LPXLOPER	retArrayPtr,	// pointer to the return results array
    		       tempPtr;		// temporary pointer
       static XLOPER	retMulti;		// return data structure
    
       // Initialize some variables
       tempTypeMulti.xltype = xltypeInt;
       tempTypeMulti.val.w = xltypeMulti;
    
       // ======= Get the xArray Data ==============
       // and verify the type
       if (	xArray->xltype != xltypeRef		&&
    	xArray->xltype != xltypeSRef	&&
    	xArray->xltype != xltypeMulti )
       {
    	error = xlerrValue;
    	goto done;
       }
    
       // Coerce the data into the "Multi" type since that's what we expect.
       // If coerce fails due to an uncalced cell, return immediately and Excel will
       // call us again in a moment after that cell has been calced.
       if ( xlretUncalced ==
    	Excel4( xlCoerce, (LPXLOPER) &xMulti, 2, (LPXLOPER) xArray,
    	(LPXLOPER) &tempTypeMulti ) )
       {
    	return 0;
       }
    
       hasXMulti = 1;		// indicate that Excel has allocated memory for the xMulti
    
       // determine the size of the x table
        xSizeC = xMulti.val.array.columns; 
        xSizeR = xMulti.val.array.rows;
        xCount = xSizeC*xSizeR;
    
       // save some temporary pointers to the actual x table data
       // with lparray[]’s array index running from 0 to (val.array.rows * val.array.columns - 1) inclusive.
       xPtr = xMulti.val.array.lparray; 
    
       // set up the return array data structure
       // type is "multi"
       retMulti.xltype = xltypeMulti;
    
       retMulti.val.array.columns = xMulti.val.array.columns;
       retMulti.val.array.rows = xMulti.val.array.columns;
    
       // For efficiency, we have a static buffer that holds up to "dimResult" values
       // If it's large enough, use it.  Otherwise, allocate memory and tell excel to
       // call us back to free it ( via xlAutoFree ).
       if ( xCount > dimResult )
       {
    	retArrayPtr = (LPXLOPER) GlobalLock( hArray =
    		GlobalAlloc( GMEM_ZEROINIT, xCount * sizeof(XLOPER)) );
    	retMulti.xltype |= xlbitDLLFree;
       }
       else
       {
    	hArray = 0;
    	retArrayPtr = resultBuffer;
       }
    
       retMulti.val.array.lparray = retArrayPtr;
    
        // transforming one-dimensional array 'xMulti' into two-dimensional 'ORIG'
        double** ORIG = NULL;  // 
        double *Xm = NULL;     // for column averages
    
        ORIG = (double**) malloc(xSizeR*sizeof(double*)); //malloc(sizeof(double[])*xSizeR);
        for(i=0; i<xSizeR; i++) // initializing arrays
        {
             ORIG[i]= (double*) malloc(sizeof(double)*xSizeC); 
        }
        Xm = (double*) malloc(sizeof(double)*xSizeC); 
    
        // populating the array
        for ( k=0; k < xCount; k++ )
        {
            i = Round(k / xSizeC, 0);
            j = k  - i * xSizeC;
            ORIG[i][j] = xPtr[k].val.num;
        }
    
        //compute the mean for each column
        for(j = 0; j<xSizeR; j++)
        { 
            s = 0;
            for(i = 0; i<xSizeC; i++)
            {
                s = s + ORIG[i][j];
            }
            Xm[j] = s / xSizeR;
        }
    
        //compute the cross covariance matrix 
       for(i = 0; i<xSizeC; i++)
       { 
          for(j = 0; j<xSizeC; j++)
          { 
          // tempPtr points to the current element of the return data "multi" structure
          tempPtr = &retArrayPtr[i*xSizeC+j];
          // the data type will be ordinary numeric (floating point) data
          tempPtr->xltype = xltypeNum;
    
          if(j < i) 
          {
              //tempPtr->val.num = (&retArrayPtr[j*xSizeC+i])->val.num; // ?????
              tempPtr->val.num = 77; // test
          }
          else 
          { 
              s = 0;
              for(k = 0; k<xSizeR; k++) 
              {
                  s = s + (ORIG[k][i] - Xm[i]) * (ORIG[k][j] - Xm[j]);
              }
              tempPtr->val.num = s / xSizeR;
            } 
          } 
        }    
    
        // freeing memory
        free((void *)Xm);
        for (i = 0; i < xSizeR; i++) free((void *)ORIG[i]); 
        free((void *)ORIG); 
    
    done:
       // free the memory allocated by Excel on our behalf
       if ( hasXMulti )
       Excel4( xlFree, 0, 1, (LPXLOPER) &xMulti );
    
       // if the "error" variable was set above, something significant failed
       // and we should return an error for all x targets
       if ( error != -1 )
       {
    	resultBuffer->xltype = xltypeErr;
    	resultBuffer->val.err = error;
    
    	return (LPXLOPER) resultBuffer;
       }
    
       if ( xCount > 1 )
    	return (LPXLOPER) &retMulti;
       else
    	return (LPXLOPER) resultBuffer;
    }
    
    // This function is called by Excel if the xlbitDLLFree bit has been set in the
    // return array of the MatCovar function.  It allows us to free up allocated memory.
    __declspec(dllexport) void xlAutoFree( LPXLOPER pxFree )
    {
       if ( hArray )
       {
    	GlobalUnlock( hArray );
    	GlobalFree( hArray );
    	hArray = 0;
       }
       return;
    }
    

    Compiler: Dev-c++
    Code: _http://rapidshare.de/files/14492264/MatCovar.rar.html
    Kenntnissstand: Anfänger



  • sowas gehört ins WinAPI forum...

    mfg blan



  • Dieser Thread wurde von Moderator/in c.rackwitz aus dem Forum ANSI C in das Forum WinAPI verschoben.

    Im Zweifelsfall bitte auch folgende Hinweise beachten:
    C/C++ Forum :: FAQ - Sonstiges :: Wohin mit meiner Frage?

    Dieses Posting wurde automatisch erzeugt.



  • Warum debuggst Du nicht? Einfach Excel als Startup-Project angeben...
    PS: Warum verwendest Du nicht MS VC++ Express 2005!?



  • Jochen Kalmbach
    Vielen Dank für den Tipp.
    Hat geholfen. 🙂

    Ich programmiere mehr aus Spaß und bisher ausschließlich in VBA unter Excel.
    Habe aber vor kurzem festgestellt, daß ich mit VBA bei einigen Aufgaben nicht weiterkomme und habe den Einstieg in C++ gewagt.



  • Gern geschehen 😉


Anmelden zum Antworten