简体   繁体   English

在内存中分配多个结构

[英]Allocate multiple structs in memory

i need pass multiple values to memory, i need make various country to CEN/XFS. 我需要将多个值传递到内存,我需要将各个国家/地区设为CEN / XFS。

This api: CashDispenser - CDM 这款api: CashDispenser-CDM

Struct reference: WFSCDMCURRENCYEXP 结构参考: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();
}
}

Your code looks very C-ish. 您的代码看起来非常C-ish。

An idiomatic way to do this in c++ would be: 在C ++中,惯用的方式是:

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. 我只是注意到您显然与c样式的API交互,因此可能需要以其原始形式使用该struct
Though in c++ you still can use a std::vector to manage a dynamically allocated, contiguous array of that struct: 尽管在c ++中,您仍然可以使用std::vector来管理该结构的动态分配的连续数组:

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];

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. 还要注意,我已经修复了.cCurrencyID的设置-字符文字(带单引号)只能包含一个字符。 To move multiple characters, you will need to call memcpy from a string. 要移动多个字符,您将需要从字符串调用memcpy。 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. 通常,我建议使用std::string而不是char [3] ,但是如果您这样做,则不能使用memcpy,并且跨DLL边界传递std::string可能不是一个好主意。

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. 您可以调用malloc来分配多个结构(如果这些结构称为POD-普通旧数据)或没有析构函数,成员函数或具有这些特征的成员类的结构。

The only reason for doing that is to be compatible with C, however, or for writing very low level code. 这样做的唯一原因是与C兼容,或者编写非常低级的代码。

As a general rule, you want to create an std::vector. 通常,您要创建一个std :: vector。 The vector handles all the memory for you, and you can push_back as many members as you require. 该向量为您处理所有内存,并且您可以根据需要push_back任意数量的成员。 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). 还有一个名为data()的成员,用于实现C兼容性(但是C不能调用您的向量,至少不容易地调用它)。

I think you try to handle WFS_INF_CDM_CURRENCY_EXP message to get information about currencies in your CDM. 我认为您尝试处理WFS_INF_CDM_CURRENCY_EXP消息以获取有关CDM中货币的信息。

Read XFS specification carefully: 仔细阅读XFS规范:

Output Param LPWFSCDMCURRENCYEXP *lppCurrencyExp; 输出参数LPWFSCDMCURRENCYEXP * lppCurrencyExp; Pointer to a NULL-terminated array of pointers to WFSCDMCURRENCYEXP structures 指向WFSCDMCURRENCYEXP结构的指针的以NULL结尾的数组的指针

This means that you must allocate an array of pointers to WFSCDMCURRENCYEXP with size N+1 and set last item to null. 这意味着您必须分配一个大小为N + 1的WFSCDMCURRENCYEXP指针数组,并将最后一项设置为null。

In CEN/XFS you cannot use standard new or malloc for memory allocation. 在CEN / XFS中,不能使用标准的new或malloc进行内存分配。 You need to use WFMAllocateBuffer and WFMAllocateMore to allocate memory for XFS structures that you return to caller. 您需要使用WFMAllocateBuffer和WFMAllocateMore为返回给调用方的XFS结构分配内存。

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. 使用XFS操作并不是那么简单。 It's too many complex API structures with different rules of allocation and data representation. 太多复杂的API结构具有不同的分配和数据表示规则。 Please read carefully XFS manuals. 请仔细阅读XFS手册。 In the first book ftp://ftp.cen.eu/CWA/CEN/WS-XFS/CWA16926/CWA%2016926-1.pdf many conceptual things is described. 在第一本书ftp://ftp.cen.eu/CWA/CEN/WS-XFS/CWA16926/CWA%2016926-1.pdf中,描述了许多概念性内容。 About configuration, memory mangement and so on. 关于配置,内存管理等。

您的代码不断抛出WFS_ERR_INTERNAL_ERROR,因为您没有完整的XFS环境设置,设置适当的配置或模拟一个(注册表项,sdk,dll等),然后再次对其进行测试,请确保您的代码包含正确的标头并确保您链接到msxfs.lib,xfs_conf.lib和xfs_supp.lib

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM