Reputation: 135
i need pass multiple values to memory, i need make various country to CEN/XFS.
This api: CashDispenser - CDM
Struct reference: WFSCDMCURRENCYEXP
How am i trying to do:
HRESULT WINAPI WFPGetInfo(HSERVICE hService, DWORD dwCategory, LPVOID lpQueryDetails, DWORD dwTimeOut, HWND hWnd, REQUESTID ReqID) {
WFSRESULT * lpWFSResult;
WFSCDMSTATUS CdmStatus;
WFSCDMCAPS CdmCapabilities;
WFSCDMCASHUNIT CdmCash;
WFSCDMCURRENCYEXP CdmCurrency;
HRESULT result;
result = WFMAllocateBuffer(sizeof(WFSRESULT), WFS_MEM_ZEROINIT | WFS_MEM_SHARE, (void**)&lpWFSResult);
if(result != WFS_SUCCESS){
return WFS_ERR_INTERNAL_ERROR;
}
if(dwCategory == WFS_INF_CDM_CURRENCY_EXP){
const int countCurrencies = 2;
WFSCDMCURRENCYEXP** ppCdmCurrencies;
result = WFMAllocateMore(sizeof(WFSCDMCURRENCYEXP*) * (countCurrencies+1), lpWFSResult, (void**)&ppCdmCurrencies);
lpWFSResult->hService=hService;
lpWFSResult->RequestID=ReqID;
lpWFSResult->u.dwEventID=WFS_INF_CDM_CURRENCY_EXP;
lpWFSResult->hResult=WFS_SUCCESS;
result = WFMAllocateMore(sizeof(WFSCDMCURRENCYEXP), lpWFSResult, (void**)&ppCdmCurrencies[0]);
WFSCDMCURRENCYEXP& cmdCurrency0(*ppCdmCurrencies[0]);
memcpy(cmdCurrency0.cCurrencyID, "AED", 3);
cmdCurrency0.sExponent = 0;
WFSCDMCURRENCYEXP& cmdCurrency1(*ppCdmCurrencies[1]);
memcpy(cmdCurrency1.cCurrencyID, "AFA", 3);
cmdCurrency1.sExponent = 0;
lpWFSResult->lpBuffer = ppCdmCurrencies;
logFile.close();
}
}
Upvotes: 0
Views: 758
Reputation: 1
your code keeps throwing WFS_ERR_INTERNAL_ERROR because you havent got a fully functional XFS environment setup, setup a proper configuration, or emulate one (registry keys, sdk, dlls, etc) and then test it again, make sure your code includes the proper headers and make sure you are linking to msxfs.lib, xfs_conf.lib and xfs_supp.lib
Upvotes: 0
Reputation: 304
I think you try to handle WFS_INF_CDM_CURRENCY_EXP message to get information about currencies in your CDM.
Read XFS specification carefully:
Output Param LPWFSCDMCURRENCYEXP *lppCurrencyExp; Pointer to a NULL-terminated array of pointers to WFSCDMCURRENCYEXP structures
This means that you must allocate an array of pointers to WFSCDMCURRENCYEXP with size N+1 and set last item to null.
In CEN/XFS you cannot use standard new or malloc for memory allocation. You need to use WFMAllocateBuffer and WFMAllocateMore to allocate memory for XFS structures that you return to caller.
For you task yo need something like this:
HRESULT WINAPI WFPGetInfo(HSERVICE hService, DWORD dwCategory, LPVOID lpQueryDetails, DWORD dwTimeOut, HWND hWnd, REQUESTID ReqID) {
WFSRESULT * lpWFSResult;
WFSCDMSTATUS CdmStatus;
WFSCDMCAPS CdmCapabilities;
WFSCDMCASHUNIT CdmCash;
WFSCDMCURRENCYEXP CdmCurrency;
HRESULT result;
result = WFMAllocateBuffer(sizeof(WFSRESULT), WFS_MEM_ZEROINIT | WFS_MEM_SHARE, (void**)&lpWFSResult);
if(result != WFS_SUCCESS){
return WFS_ERR_INTERNAL_ERROR;
}
if(dwCategory == WFS_INF_CDM_CURRENCY_EXP){
const int countCurrencies = 2;
WFSCDMCURRENCYEXP** ppCdmCurrencies;
result = WFMAllocateBuffer(sizeof(WFSCDMCURRENCYEXP*) * (countCurrencies+1), WFS_MEM_ZEROINIT | WFS_MEM_SHARE, (void**)&ppCdmCurrencies);
lpWFSResult->hService=hService;
lpWFSResult->RequestID=ReqID;
lpWFSResult->u.dwEventID=WFS_INF_CDM_CURRENCY_EXP;
lpWFSResult->hResult=WFS_SUCCESS;
result = WFMAllocateMore(sizeof(WFSCDMCURRENCYEXP), lpWFSResult, (void**)&ppCdmCurrencies[0]);
WFSCDMCURRENCYEXP& cmdCurrency0(*ppCdmCurrencies[0]);
memcpy(cmdCurrency0.cCurrencyID, "AED", 3);
cmdCurrency0.sExponent = 0;
result = WFMAllocateMore(sizeof(WFSCDMCURRENCYEXP), lpWFSResult, (void**)&ppCdmCurrencies[1]);
WFSCDMCURRENCYEXP& cmdCurrency1(*ppCdmCurrencies[1]);
memcpy(cmdCurrency1.cCurrencyID, "AFA", 3);
cmdCurrency1.sExponent = 0;
lpWFSResult->lpBuffer = ppCdmCurrencies;
logFile.close();
return WFS_SUCCESS;
}
}
That's not so simple to manipulate with XFS. It's too many complex API structures with different rules of allocation and data representation. Please read carefully XFS manuals. In the first book ftp://ftp.cen.eu/CWA/CEN/WS-XFS/CWA16926/CWA%2016926-1.pdf many conceptual things is described. About configuration, memory mangement and so on.
Upvotes: 0
Reputation: 1
Your code looks very C-ish.
An idiomatic way to do this in c++ would be:
struct WFSCDMCURRENCYEXP
{
std::string cCurrencyID;
SHORT sExponent;
};
std::vector<WFSCDMCURRENCYEXP> CdmCurrencies {
{ "ARG", 3 } ,
{ "EUA", 3 } ,
// lots more countries
};
Update:
I just noticed you apparently interact with a c-style API, and using that struct
might be required in its original form.
Though in c++ you still can use a std::vector
to manage a dynamically allocated, contiguous array of that struct:
typedef struct _wfs_cdm_currency_exp
{
CHAR cCurrencyID[3];
SHORT sExponent;
} WFSCDMCURRENCYEXP, * LPWFSCDMCURRENCYEXP;
std::vector<WFSCDMCURRENCYEXP> CdmCurrencies {
{ { 'A', 'R', 'G' }, 3 } , // Note that the cCurrencyID is a non null terminated
// array here
{ { 'E', 'U', 'A' }, 3 } ,
// lots more countries
};
LPWFSCDMCURRENCYEXP pCdmCurrencies = &CdmCurrencies[0];
Upvotes: 3
Reputation: 6404
You can call malloc to allocate multiple structs, if they are what is called POD - plain old data - or structures with no destructors, member functions, or member classes with these characteristics.
The only reason for doing that is to be compatible with C, however, or for writing very low level code.
As a general rule, you want to create an std::vector. The vector handles all the memory for you, and you can push_back as many members as you require. Use reserve (or resize) if efficiency is important. There's also a member called data() which is there for C compatibility (however C can't call your vector, at least not easily).
Upvotes: 0
Reputation: 29017
Declare an array:
WFSCDMCURRENCYEXP CdmCurrency[2];
memcpy( CdmCurrency[0].cCurrencyID, "ARG", 3);
CdmCurrency[0].sExponent = 0;
memcpy( CdmCurrency[1].cCurrencyID, "EUA", 3);
CdmCurrency[1].sExponent = 0;
memcpy(lpWFSResult->lpBuffer, CdmCurrency, 2*sizeof(WFSCDMCURRENCYEXP));
// ^^
Don't forget you will need to copy more memory.
Also note I have fixed the setting of .cCurrencyID
- a character literal (with single quotes) can only contain a single character. To move multiple characters, you will need to call memcpy from a string. Normally I would suggest using std::string
rather than char [3]
, but you can't use memcpy if you do, and it probably wouldn't be a good idea to pass a std::string
across a DLL boundary.
Upvotes: 1