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
