New BSFN compile errors

DaveJohnson

Member
Using VS 2005, E9.0, I have created a business function from scratch, added a test data structure and pasted the typedef in the .h

If I add any reference to NID like:
#define NUMCOLS 2
NID szArray[NUMCOLS] = {NID_DOCO,NID_DCTO};


I get the following errors, JDE support is taking its time with this. Can anyone shed some light?

B56TEST.c

c:\e900\DV900\source\B56TEST.c(79) : error C2275: 'NID' : illegal use of this type as an expression

c:\e900\SYSTEM\include\jdetypes.h(171) : see declaration of 'NID'

c:\e900\DV900\source\B56TEST.c(79) : error C2146: syntax error : missing ';' before identifier 'szArray'

c:\e900\DV900\source\B56TEST.c(79) : error C2065: 'szArray' : undeclared identifier

c:\e900\DV900\source\B56TEST.c(79) : error C2109: subscript requires array or pointer type

c:\e900\DV900\source\B56TEST.c(79) : error C2059: syntax error : '{'

jdertdll.c
 
To keep it simple I created:


/*****************************************************************************
* Header File: B56TEST.h
*
* Description: Test for NID errors Header File
*
* History:
* Date Programmer SAR# - Description
* ---------- ---------- -------------------------------------------
* Author 10/16/09 Unkno Unknown - Created
*
*
* Copyright (c) J.D. Edwards World Source Company, 1996
*
* This unpublished material is proprietary to J.D. Edwards World Source
* Company. All rights reserved. The methods and techniques described
* herein are considered trade secrets and/or confidential. Reproduction
* or distribution, in whole or in part, is forbidden except by express
* written permission of J.D. Edwards World Source Company.
****************************************************************************/

#ifndef __B56TEST_H
#define __B56TEST_H

/*****************************************************************************
* Table Header Inclusions
****************************************************************************/

/*****************************************************************************
* External Business Function Header Inclusions
****************************************************************************/

/*****************************************************************************
* Global Definitions
****************************************************************************/

/*****************************************************************************
* Structure Definitions
****************************************************************************/
/*****************************************
* TYPEDEF for Data Structure
* Template Name: Test for NID errors
* Template ID: D56TEST
* Generated: Fri Oct 16 08:08:51 2009
*
* DO NOT EDIT THE FOLLOWING TYPEDEF
* To make modifications, use the OneWorld Data Structure
* Tool to Generate a revised version, and paste from
* the clipboard.
*
**************************************/

#ifndef DATASTRUCTURE_D56TEST
#define DATASTRUCTURE_D56TEST

typedef struct tagDSD56TEST
{
MATH_NUMERIC mnDocumentOrderInvoiceE;
JCHAR szOrderType[3];
} DSD56TEST, *LPDSD56TEST;

#define IDERRmnDocumentOrderInvoiceE_1 1L
#define IDERRszOrderType_2 2L

#endif

/*****************************************************************************
* DS Template Type Definitions
****************************************************************************/

/*****************************************************************************
* Source Preprocessor Definitions
****************************************************************************/
#if defined (JDEBFRTN)
#undef JDEBFRTN
#endif

#if defined (WIN32)
#if defined (WIN32)
#define JDEBFRTN(r) __declspec(dllexport) r
#else
#define JDEBFRTN(r) __declspec(dllimport) r
#endif
#else
#define JDEBFRTN(r) r
#endif

/*****************************************************************************
* Business Function Prototypes
****************************************************************************/
JDEBFRTN (ID) JDEBFWINAPI TestBSFN (LPBHVRCOM lpBhvrCom, LPVOID lpVoid, LPDSD56TEST lpDS);


/*****************************************************************************
* Internal Function Prototypes
****************************************************************************/

#endif /* __B56TEST_H */

/************************************************/
/************************************************/
/************************************************/


#include <jde.h>

#define b56test_c


/*****************************************************************************
* Source File: b56test
*
* Description: Test for NID errors Source File
*
* History:
* Date Programmer SAR# - Description
* ---------- ---------- -------------------------------------------
* Author 10/16/09 Unkno Unknown - Created
*
* Copyright (c) J.D. Edwards World Source Company, 1996
*
* This unpublished material is proprietary to J.D. Edwards World Source Company.
* All rights reserved. The methods and techniques described herein are
* considered trade secrets and/or confidential. Reproduction or
* distribution, in whole or in part, is forbidden except by express
* written permission of J.D. Edwards World Source Company.
****************************************************************************/
/**************************************************************************
* Notes:
*
**************************************************************************/

#include <b56test.h>


/**************************************************************************
* Business Function: TestBSFN
*
* Description: Test Business Function
*
* Parameters:
* LPBHVRCOM lpBhvrCom Business Function Communications
* LPVOID lpVoid Void Parameter - DO NOT USE!
* LPDSD56T lpDS Parameter Data Structure Pointer
*
*************************************************************************/

JDEBFRTN (ID) JDEBFWINAPI TestBSFN (LPBHVRCOM lpBhvrCom, LPVOID lpVoid, LPDSD56TEST lpDS)

{
/************************************************************************
* Variable declarations
************************************************************************/

/************************************************************************
* Declare structures
************************************************************************/

/************************************************************************
* Declare pointers
************************************************************************/

/************************************************************************
* Check for NULL pointers
************************************************************************/
if ((lpBhvrCom == (LPBHVRCOM) NULL) ||
(lpVoid == (LPVOID) NULL) ||
(lpDS == (LPDSD56TEST) NULL))
{
jdeErrorSet (lpBhvrCom, lpVoid, (ID) 0, _J("4363"), (LPVOID) NULL);
return ER_ERROR;
}

/************************************************************************
* Set pointers
************************************************************************/

/************************************************************************
* Main Processing
************************************************************************/
#define NUMCOLS 2

NID szArray[NUMCOLS] = {NID_DOCO,NID_DCTO};

/************************************************************************
* Function Clean Up
************************************************************************/

return (ER_SUCCESS);
}

/* Internal function comment block */
/**************************************************************************
* Function: Ixxxxxxx_a // Replace "xxxxxxx" with source file number
* // and "a" with the function name
* Notes:
*
* Returns:
*
* Parameters:
**************************************************************************/
 
Dave,

Move

#define NUMCOLS 2
NID szArray[NUMCOLS] = {NID_DOCO,NID_DCTO};

to the top of the function, right after the variable declarations comment section. i.e. before any code.

You can also get rid of the #define and just do:

NID szArray[] = {NID_DOCO,NID_DCTO};
 
To elaborate on Craig's comments, your issue isn't the code you have, but the location of that code.

It's not a good programming practice to mingle variable declarations with code. Keeping the data and code sectors separate helps with readability and portability. It also lets the compiler decide how much memory to set aside on the stack in the very beginning, without having to look around. I don't know if you're actually hurting anything by using that method, but some compilers, including visual studio, simply won't let you do it.

As a side, and this will only affect you cosmetically, you may want to move the "#define" outside of that function, maybe even at the top of your source file (or better, at the top of the header). Either won't hurt your code, but when you code bigger things you'll want to have a separate spot for your pre-processor directives, so it's easier to change them should you need to.

It looks like you're either just starting C programming, brushing up on it. I, and many of the others here, will be more than happy to help. My company is currently upgrading to 9.0 and it's my job to do all the business functions, so my mind is especially fresh.
 
Hi Gary,

Thanks for the explanation but I think one point needs to be cleared. All JDE business functions are compiled to ANSI C standards to ensure compatibility across platforms, as you stated. And it is the ANSI C standard that dictates all variables be declared before statements.

Modern languages (C++, Java, non ANSI C etc.) allow variable declaration at any place in the function and can be scoped within a block {...} While misuse of this can create hard to follow code (i.e. using the same variable name twice), when done correctly some find the program easier to read.
 
And to add further to that. ANSI C will let you properly scope your variables as well which I would consider good programming practice. In other words, ANSI C requires you to declare variables before statements within a given block. So the following is valid:


int nCondition = 0, nTotalCount = 0, *pArray;

....

if(nCondition != 0 && nTotalCount > 0)
{
int i;
for(i = 0; i < nTotalCount; i++)
{
int *pArrayTmp = pArray + i;
//do somthing with pArrayTmp
}
}


And, IMO, preferable to:


int nCondition = 0, nTotalCount = 0, *pArray, i, *pArrayTmp;

....

if(nCondition != 0 && nTotalCount > 0)
{
for(i = 0; i < nTotalCount; i++)
{
*pArrayTmp = pArray + i;
//do somthing with pArrayTmp
}
}
 
Thanks for the correction. It's been so long since I've tested the variable place, I had forgotten it was an actual requirement rather than a good habit. I also agree that the decision to declare variables inside a code block can be beneficial, especially when coding in an environment like JDE, where you add a modification in a block. In all circumstances, keeping your variables separate from your code is good.
 
Back
Top