Hi everyone.
So, after much coercion, I finally have my first extended stored
procedure compiled and (apparently) installed on the server. It's just
the xp_hello example off the MS website.
I have followed these instructions exactly:
http://msdn.microsoft.com/library/d.../>
01_26hx.asp
but when I try to execute the procedure I get this error message:
Cannot load the DLL c:\Program Files\Microsoft SQL
Server\80\Tools\Binn\xp_hello.dll, or one of the DLLs it references.
Reason: 998(Invalid access to memory location.).
I assume from this that the DLL is registered and accessible by the
server, but there is some internal problem. Anyone know what it means?
Additional info:
I am linking the following files:
kernel32.lib user32.lib gdi32.lib comctl32.lib comdlg32.lib advapi32.lib
delayimp.lib OPENDS60.LIB
The final one is the version off the SQL Server 2000 CD. I also swiped
the latest svr.h and w95scm.lib and the CD and put them in my
include/library paths respectively.
Below is the entire source code. It's exactly what's given by MS plus a
definition for the DllMain() function. I think this is necessary
because I am compiling with the Pelles C compiler rather than in Visual C++.
Thanks in advance for your help.
Mike
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <windows.h>
#include <time.h>
#include <srv.h>
// Macros -- return codes
#define XP_NOERROR 0
#define XP_ERROR 1
#define MAX_SERVER_ERROR 20000
#define XP_HELLO_ERROR MAX_SERVER_ERROR+1
void printUsage (SRV_PROC* pSrvProc);
void printError (SRV_PROC *pSrvProc, CHAR* szErrorMsg);
// It is highly recommended that all Microsoft SQL Server (7.0
// and greater) extended stored procedure DLLs implement and export
// __GetXpVersion. For more information see SQL Server
// Books Online
ULONG __GetXpVersion()
{
return ODS_VERSION;
}
int DllMain()
{
return TRUE;
}
SRVRETCODE xp_hello(SRV_PROC* pSrvProc)
{
char szText[15] = "Hello World!";
BYTE bType;
long cbMaxLen;
long cbActualLen;
BOOL fNull;
#ifdef _DEBUG
// In a debug build, look up the data type name for assistance.
DBCHAR* pdbcDataType;
int cbDataType;
#endif
// Count up the number of input parameters. There should only be one.
if (srv_rpcparams(pSrvProc) != 1)
{
// Send error message and return
//
printUsage (pSrvProc);
return (XP_ERROR);
}
// Use srv_paraminfo to get data type and length information.
if (srv_paraminfo(pSrvProc, 1, &bType, &cbMaxLen, &cbActualLen,
NULL, &fNull) == FAIL)
{
printError (pSrvProc, "srv_paraminfo failed...");
return (XP_ERROR);
}
// Make sure first parameter is a return (OUTPUT) parameter
if ((srv_paramstatus(pSrvProc, 1) & SRV_PARAMRETURN) == FAIL)
{
printUsage (pSrvProc);
return (XP_ERROR);
}
// Make sure first parameter is of char or varchar datatype
if (bType != SRVBIGVARCHAR && bType != SRVBIGCHAR)
{
printUsage (pSrvProc);
return (XP_ERROR);
}
// Make sure first paramter is large enough to hold data
if (cbMaxLen < (long)strlen(szText))
{
printError (pSrvProc, "output param max. length should be bigger");
return (XP_ERROR);
}
// Describe the results set
//#define METHOD1
#ifdef METHOD1
srv_describe(pSrvProc, 1, "Column 1", SRV_NULLTERM, bType,
cbMaxLen, bType, strlen(szText), szText);
#else
srv_describe(pSrvProc, 1, "Column 1", SRV_NULLTERM, bType,
cbMaxLen, bType, 0, NULL);
// Set the column's length
if (srv_setcollen(pSrvProc, 1, strlen(szText)) == FAIL)
{
printError (pSrvProc, "srv_setcollen failed...");
return (XP_ERROR);
}
// Set the column's data
if (srv_setcoldata(pSrvProc, 1, szText) == FAIL)
{
printError (pSrvProc, "srv_setcoldata failed...");
return (XP_ERROR);
}
#endif //METHOD1
// Send a row to client
if (srv_sendrow(pSrvProc) == FAIL)
{
printError (pSrvProc, "srv_sendrow failed...");
return (XP_ERROR);
}
// Set the output parameter
if (FAIL == srv_paramsetoutput(pSrvProc, 1, szText, strlen(szText),
FALSE))
{
printError (pSrvProc, "srv_paramsetoutput failed...");
return (XP_ERROR);
}
srv_senddone(pSrvProc, (SRV_DONE_COUNT | SRV_DONE_MORE), 0, 1);
return (XP_NOERROR);
}
// send XP usage info to client
void printUsage (SRV_PROC *pSrvProc)
{
// usage: exec xp_hello <@.param1 output>
// Example:
// declare @.txt varchar(33)
// exec xp_hello @.txt OUTPUT
// select @.txt
srv_sendmsg(pSrvProc, SRV_MSG_ERROR, XP_HELLO_ERROR, SRV_INFO, 1,
NULL, 0, (DBUSMALLINT) __LINE__,
"Usage: exec xp_hello <@.param1 output>",
SRV_NULLTERM);
srv_senddone(pSrvProc, (SRV_DONE_ERROR | SRV_DONE_MORE), 0, 0);
}
// send szErrorMsg to client
void printError (SRV_PROC *pSrvProc, CHAR* szErrorMsg)
{
srv_sendmsg(pSrvProc, SRV_MSG_ERROR, XP_HELLO_ERROR, SRV_INFO, 1,
NULL, 0, (DBUSMALLINT) __LINE__,
szErrorMsg,
SRV_NULLTERM);
srv_senddone(pSrvProc, (SRV_DONE_ERROR | SRV_DONE_MORE), 0, 0);
}Hi Mike
I don't have the facilities to check out the compilation of the code, but
your error is a straight access violation
http://support.microsoft.com/defaul...kb;en-us;196069
If you didn't cut and paste the code then check it out for typos, you should
be using the headers and libraries that correspond to the installed revision
of SQL Server, and you may want to look for a machine with VC++ on it to rul
e
out compiler differences.
John
"Mike Chamberlain" wrote:
> Hi everyone.
> So, after much coercion, I finally have my first extended stored
> procedure compiled and (apparently) installed on the server. It's just
> the xp_hello example off the MS website.
> I have followed these instructions exactly:
> http://msdn.microsoft.com/library/d...
n_01_26hx.asp
> but when I try to execute the procedure I get this error message:
> Cannot load the DLL c:\Program Files\Microsoft SQL
> Server\80\Tools\Binn\xp_hello.dll, or one of the DLLs it references.
> Reason: 998(Invalid access to memory location.).
> I assume from this that the DLL is registered and accessible by the
> server, but there is some internal problem. Anyone know what it means?
> Additional info:
> I am linking the following files:
> kernel32.lib user32.lib gdi32.lib comctl32.lib comdlg32.lib advapi32.lib
> delayimp.lib OPENDS60.LIB
> The final one is the version off the SQL Server 2000 CD. I also swiped
> the latest svr.h and w95scm.lib and the CD and put them in my
> include/library paths respectively.
> Below is the entire source code. It's exactly what's given by MS plus a
> definition for the DllMain() function. I think this is necessary
> because I am compiling with the Pelles C compiler rather than in Visual C+
+.
> Thanks in advance for your help.
> Mike
>
> #include <stdlib.h>
> #include <stdio.h>
> #include <string.h>
> #include <ctype.h>
> #include <windows.h>
> #include <time.h>
> #include <srv.h>
>
> // Macros -- return codes
> #define XP_NOERROR 0
> #define XP_ERROR 1
> #define MAX_SERVER_ERROR 20000
> #define XP_HELLO_ERROR MAX_SERVER_ERROR+1
> void printUsage (SRV_PROC* pSrvProc);
> void printError (SRV_PROC *pSrvProc, CHAR* szErrorMsg);
> // It is highly recommended that all Microsoft? SQL Server (7.0
> // and greater) extended stored procedure DLLs implement and export
> // __GetXpVersion. For more information see SQL Server
> // Books Online
> ULONG __GetXpVersion()
> {
> return ODS_VERSION;
> }
> int DllMain()
> {
> return TRUE;
> }
> SRVRETCODE xp_hello(SRV_PROC* pSrvProc)
> {
> char szText[15] = "Hello World!";
> BYTE bType;
> long cbMaxLen;
> long cbActualLen;
> BOOL fNull;
> #ifdef _DEBUG
> // In a debug build, look up the data type name for assistance.
> DBCHAR* pdbcDataType;
> int cbDataType;
> #endif
> // Count up the number of input parameters. There should only be one
.
> if (srv_rpcparams(pSrvProc) != 1)
> {
> // Send error message and return
> //
> printUsage (pSrvProc);
> return (XP_ERROR);
> }
> // Use srv_paraminfo to get data type and length information.
> if (srv_paraminfo(pSrvProc, 1, &bType, &cbMaxLen, &cbActualLen,
> NULL, &fNull) == FAIL)
> {
> printError (pSrvProc, "srv_paraminfo failed...");
> return (XP_ERROR);
> }
> // Make sure first parameter is a return (OUTPUT) parameter
> if ((srv_paramstatus(pSrvProc, 1) & SRV_PARAMRETURN) == FAIL)
> {
> printUsage (pSrvProc);
> return (XP_ERROR);
> }
> // Make sure first parameter is of char or varchar datatype
> if (bType != SRVBIGVARCHAR && bType != SRVBIGCHAR)
> {
> printUsage (pSrvProc);
> return (XP_ERROR);
> }
> // Make sure first paramter is large enough to hold data
> if (cbMaxLen < (long)strlen(szText))
> {
> printError (pSrvProc, "output param max. length should be bigger"
);
> return (XP_ERROR);
> }
> // Describe the results set
> //#define METHOD1
> #ifdef METHOD1
> srv_describe(pSrvProc, 1, "Column 1", SRV_NULLTERM, bType,
> cbMaxLen, bType, strlen(szText), szText);
> #else
> srv_describe(pSrvProc, 1, "Column 1", SRV_NULLTERM, bType,
> cbMaxLen, bType, 0, NULL);
> // Set the column's length
> if (srv_setcollen(pSrvProc, 1, strlen(szText)) == FAIL)
> {
> printError (pSrvProc, "srv_setcollen failed...");
> return (XP_ERROR);
> }
> // Set the column's data
> if (srv_setcoldata(pSrvProc, 1, szText) == FAIL)
> {
> printError (pSrvProc, "srv_setcoldata failed...");
> return (XP_ERROR);
> }
> #endif //METHOD1
>
> // Send a row to client
> if (srv_sendrow(pSrvProc) == FAIL)
> {
> printError (pSrvProc, "srv_sendrow failed...");
> return (XP_ERROR);
> }
> // Set the output parameter
> if (FAIL == srv_paramsetoutput(pSrvProc, 1, szText, strlen(szText),
> FALSE))
> {
> printError (pSrvProc, "srv_paramsetoutput failed...");
> return (XP_ERROR);
> }
> srv_senddone(pSrvProc, (SRV_DONE_COUNT | SRV_DONE_MORE), 0, 1);
> return (XP_NOERROR);
> }
> // send XP usage info to client
> void printUsage (SRV_PROC *pSrvProc)
> {
> // usage: exec xp_hello <@.param1 output>
> // Example:
> // declare @.txt varchar(33)
> // exec xp_hello @.txt OUTPUT
> // select @.txt
> srv_sendmsg(pSrvProc, SRV_MSG_ERROR, XP_HELLO_ERROR, SRV_INFO, 1,
> NULL, 0, (DBUSMALLINT) __LINE__,
> "Usage: exec xp_hello <@.param1 output>",
> SRV_NULLTERM);
> srv_senddone(pSrvProc, (SRV_DONE_ERROR | SRV_DONE_MORE), 0, 0);
> }
> // send szErrorMsg to client
> void printError (SRV_PROC *pSrvProc, CHAR* szErrorMsg)
> {
> srv_sendmsg(pSrvProc, SRV_MSG_ERROR, XP_HELLO_ERROR, SRV_INFO, 1,
> NULL, 0, (DBUSMALLINT) __LINE__,
> szErrorMsg,
> SRV_NULLTERM);
> srv_senddone(pSrvProc, (SRV_DONE_ERROR | SRV_DONE_MORE), 0, 0);
> }
>
No comments:
Post a Comment