Thread View: comp.os.ms-windows.programmer.misc
1 messages
1 total messages
Started by guthrie
Wed, 30 Aug 1995 03:31
Help: XLL programming problem...
Author: guthrie
Date: Wed, 30 Aug 1995 03:31
Date: Wed, 30 Aug 1995 03:31
401 lines
10601 bytes
10601 bytes
Summary: trying simple .XLL example, get odd illogical C-code effects;
is it a compiler bug??
------------------------------------------------
I am writing my first Excel DLL, and got it to work fine. :-)
But, to make it into an .XLL I am starting with a sample (From
Compuserve..) called poly.xll, which GPFs whenever I try it. This
sample was distributed with a Borland compiled binary, and source
code. The binary works, but a recompiled Msoft.VC++ (1.50) version
GPFs.
The sample is nearly a clone of the Excel SDK examples (which do
work..), and in debugging it I get a really mysterious error.
Basically, the function registration name table is a static global,
and in LibMain (as always) it gets LPSTR'ed.
But, the next routine of mine that is called is xlAutoOpen, and in the
first statement of that routine I can no longer access the addresses
of the entries in this table. A piece of identical test code in each
of these two routines,
char* atest = rgFuncs[0][6]; /* Test */
gets different values when accessing the rgFuncs[0][i] values. One
could suspect that somehow they got clobbered in the interim, but
not-so, one can look at the right-hand-side of the test statement
(debugger/watch), and it is OK, only the value is not accessed
properly. This same bad effect occurs when these (correct global)
values are passed to TmpStr(), which is the cause of the original GPF.
This looks like a compiler bug to me, but seems so odd that I thought
I should seek some other advice/opinions.
Any ideas appreciated!!
Gregory Guthrie
attachments: 1) debugging summary;
2) full code of failing routine.
-===================================================================--
----------------------------------
// structure containing function registration info
// see MS Excel SDK for additional details
static LPSTR rgFuncs[rgFuncsRows][7] =
{
{" Poly2", " EEEEE", " Poly2"," ", " 1", " ", "
"}
};
---------------------------------------------------------------------
int FAR PASCAL LibMain(HANDLE hInstance, WORD wDataSeg,
WORD wHeapSize, LPSTR lpszCmdLine)
{
static int i,j;
char* atest = rgFuncs[0][6]; /* Test */
/** byte count local strings. **/
for (i=0; i<rgFuncsRows; i++)
{
for (j=0; j<7; j++)
{
atest = rgFuncs[i][j]; /* Test : good */
rgFuncs[i][j][0] = (BYTE) lstrlen (rgFuncs[i][j]+1);
}
}
InitFramework();
return 1;
}
---------------------------------------------------------------------
int FAR PASCAL xlAutoOpen(void)
{
char tmp[512]="\0";
static XLOPER xDLL; /* name of this DLL */
int i; /* Loop index */
char* btest = rgFuncs[0][6]; /* Test : RHS=good, LHS=bad */
LPSTR ctest = rgFuncs[0][6]; /* Test : RHS=good, LHS=bad */
Excel(xlGetName, &xDLL, 0);
for (i=0; i<rgFuncsRows; i++){
Excel(xlfRegister, 0, 8,
(LPXLOPER) &xDLL,
(LPXLOPER) TempStr(rgFuncs[i][0]),
(LPXLOPER) TempStr(rgFuncs[i][1]),
(LPXLOPER) TempStr(rgFuncs[i][2]),
(LPXLOPER) TempStr(rgFuncs[i][3]),
(LPXLOPER) TempStr(rgFuncs[i][4]),
(LPXLOPER) TempStr(rgFuncs[i][5]),
(LPXLOPER) TempStr(rgFuncs[i][6]));
}
---------------------------------------------------------------------
atest = CXX0030: Error: expression cannot be evaluated
+btest = 0x0001:0x0001 "" <-------bad
+ctest = 0x0001:0x0001 ""
-rgFuncs[0][6] = 0x39A7:0x002C "" <-------good
= 0 ''
--------------------------------------------------------------------
LPXLOPER TempStr(LPSTR lpstr)
{
LPXLOPER lpx;
char* atest = lpstr; /* Test : bad */
LPSTR ctest = lpstr; /* Test : bad */
.......
-===================================================================--
b) Full code of failing example follows:
/*
** poly.xll
**
** This source code demonstrates how to create a VERY simple
** Excel Add-In (*.XLL). In this example the function "Poly2"
** evaluates a 2nd-order polynomial given x and the coeficients
** a, b, and c.
**
** Poly2(x,a,b,c) returns a*x^2 + b*x + c
**
** The following code takes advantage of MUCH code (GENERIC.C)
** supplied with "MICROSOFT EXCEL SOFTWARE DEVELOPMENT KIT."
** You will need the following files:
**
** framewrk.c (supplied with MS Excel SDK)
** There's a new file on CIS, I believe with the
** same name. It fixes a problem with xlCoerce.
** It is not necessary for this demo.
**
** xlcall.dll (supplied with Excel)
** xlcall.lib (supplied with MS Excel SDK)
** You may need to create this file with
** a tool such as implib supplied with BC++.
** It seems reasonable that this may only
** be necessary for non-MS compilers/linkers.
** If you really want to know, ask an expert.
**
**
**
** bob walker
*/
#define XLLNAME "Sample EXCEL Add-In"
#define LASTREV "1/28/95"
#define FUNC1 Poly2
#define NAME1 " Poly2"
// For some reason??? The following macro is NOT required
// when compiling with Turbo C++ 3.1
#define LPDOUBLE double*
#include <ctype.h>
#include <string.h>
#include <windows.h>
#include <xlcall.h> // supplied by MS EXCEL SDK
#include "framewrk.h" // supplied by MS EXCEL SDK
#define rgFuncsRows 1
// function prototype for exported function Poly2()
LPDOUBLE FAR PASCAL FUNC1(LPDOUBLE x,
LPDOUBLE a,
LPDOUBLE b,
LPDOUBLE c);
// structure containing function registration info
// see MS Excel SDK for additional details
static LPSTR rgFuncs[rgFuncsRows][7] =
{
{" Poly2", " EEEEE", " Poly2"," ", " 1", " ", "
"}
};
// the Poly2() function
// looks odd, I know
LPDOUBLE FAR PASCAL FUNC1(LPDOUBLE x,
LPDOUBLE a,
LPDOUBLE b,
LPDOUBLE c)
{
static double y;
y=(*a)*(*x)*(*x)+(*b)*(*x)+(*c);
return (LPDOUBLE) &y;
}
/*============================================================*/
/*
** LibMain
*/
#pragma argsused
int FAR PASCAL LibMain(HANDLE hInstance, WORD wDataSeg,
WORD wHeapSize, LPSTR lpszCmdLine)
{
static int i,j;
char* atest = rgFuncs[0][6]; /* Test */
/** byte count local strings..
**/
for (i=0; i<rgFuncsRows; i++)
{
for (j=0; j<7; j++)
{
atest = rgFuncs[i][j]; /* Test */
rgFuncs[i][j][0] = (BYTE) lstrlen
(rgFuncs[i][j]+1);
}
}
InitFramework();
return 1;
}
/*
** WEP
*/
#pragma argsused
int FAR PASCAL WEP (int nArgument)
{
return 1;
}
/*
** xlAutoOpen
** return 1 if successful, or return 0 if your XLL cannot be opened.
*/
int FAR PASCAL xlAutoOpen(void)
{
char tmp[512]="\0";
static XLOPER xDLL; /* name of this DLL */
int i; /* Loop index */
char* btest = rgFuncs[0][6]; /* Test */
LPSTR ctest = rgFuncs[0][6]; /* Test */
Excel(xlGetName, &xDLL, 0);
for (i=0; i<rgFuncsRows; i++){
Excel(xlfRegister, 0, 8,
(LPXLOPER) &xDLL,
(LPXLOPER) TempStr(rgFuncs[i][0]),
(LPXLOPER) TempStr(rgFuncs[i][1]),
(LPXLOPER) TempStr(rgFuncs[i][2]),
(LPXLOPER) TempStr(rgFuncs[i][3]),
(LPXLOPER) TempStr(rgFuncs[i][4]),
(LPXLOPER) TempStr(rgFuncs[i][5]),
(LPXLOPER) TempStr(rgFuncs[i][6]));
}
Excel(xlFree, 0, 1, (LPXLOPER) &xDLL);
strcat(tmp, " Congratulations!\n");
strcat(tmp,"Poly.Xll has been loaded -- .\n\n");
strcat(tmp,"Poly2(x,a,b,c)=a*x^2+bx+c\n");
tmp[0]=strlen(tmp)-1;
Excel(xlcAlert, 0, 2, TempStr(tmp), TempInt(2));
return 1;
}
/*
** xlAutoClose
** should return 1.
*/
int FAR PASCAL xlAutoClose(void)
{
int i;
for (i=0; i<rgFuncsRows; i++){
Excel(xlfSetName, 0, 1, TempStr(rgFuncs[i][2]));
}
return 1;
}
/*
** lpstricmp
*/
int PASCAL lpstricmp(LPSTR s, LPSTR t)
{
int i;
if (*s != *t) return 1;
for (i=1; i<=s[0]; i++){
if (tolower(s[i]) != tolower(t[i])){
return 1;
}
}
return 0;
}
/*
** xlAutoRegister
*/
LPXLOPER FAR PASCAL xlAutoRegister(LPXLOPER pxName)
{
static XLOPER xDLL, xRegId;
int i;
xRegId.xltype = xltypeErr;
xRegId.val.err = xlerrValue;
for (i=0; i<rgFuncsRows; i++){
if (!lpstricmp(rgFuncs[i][0], pxName->val.str)){
Excel(xlGetName, &xDLL, 0);
Excel(xlfRegister, 0, 8,
(LPXLOPER) &xDLL,
(LPXLOPER) TempStr(rgFuncs[i][0]),
(LPXLOPER) TempStr(rgFuncs[i][1]),
(LPXLOPER) TempStr(rgFuncs[i][2]),
(LPXLOPER) TempStr(rgFuncs[i][3]),
(LPXLOPER) TempStr(rgFuncs[i][4]),
(LPXLOPER) TempStr(rgFuncs[i][5]),
(LPXLOPER) TempStr(rgFuncs[i][6]));
Excel(xlFree, 0, 1, (LPXLOPER) &xDLL);
return (LPXLOPER) &xRegId;
}
}
return (LPXLOPER) &xRegId;
}
/*
** xlAutoAdd
*/
int FAR PASCAL xlAutoAdd(void)
{
/* Display a dialog box indicating that the XLL was successfully
added */
Excel(xlcAlert, 0, 2, TempStr(" Thank you for adding Poly
XLL!"),
TempInt(2));
return 1;
}
/*
** xlAutoRemove
*/
int FAR PASCAL xlAutoRemove(void)
{
/* Display a dialog box indicating that the XLL was successfully
removed */
Excel(xlcAlert, 0, 2, TempStr(" Thank you for removing Poly
XLL!"),
TempInt(2));
return 1;
}
/* xlAddInManagerInfo
**
*/
LPXLOPER FAR PASCAL xlAddInManagerInfo(LPXLOPER xAction)
{
static XLOPER xInfo, xIntAction;
Excel(xlCoerce, &xIntAction, 2, xAction, TempInt(xltypeInt));
if(xIntAction.val.w==1){
xInfo.xltype = xltypeStr;
xInfo.val.str = "\026POLY SAMPLE DLL";
}
else{
xInfo.xltype = xltypeErr;
xInfo.val.err = xlerrValue;
}
return (LPXLOPER) &xInfo;
}
Thread Navigation
This is a paginated view of messages in the thread with full content displayed inline.
Messages are displayed in chronological order, with the original post highlighted in green.
Use pagination controls to navigate through all messages in large threads.
Back to All Threads