在内存中分配多个结构

Allocate multiple structs in memory

我需要将多个值传递给内存,我需要将各个国家/地区设置为 CEN/XFS。

这个api:CashDispenser - CDM

结构参考:WFSCDMCURRENCYEXP

我要怎么做:

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();
}
}

声明一个数组:

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));
//                                         ^^

别忘了你需要复制更多内存。

另请注意,我已修复 .cCurrencyID 的设置 - 字符文字(带单引号)只能包含单个字符。要移动多个字符,您需要从字符串中调用 memcpy。通常我会建议使用 std::string 而不是 char [3],但是如果你这样做你就不能使用 memcpy,并且在 DLL 中传递 std::string 可能不是一个好主意边界.

您可以调用 malloc 来分配多个结构,如果它们是所谓的 POD(普通旧数据)或没有析构函数、成员函数或具有这些特征的成员 类 的结构。

这样做的唯一原因是为了与 C 兼容,或者为了编写非常低级的代码。

一般来说,您要创建一个 std::vector。 vector 为您处理所有内存,您可以根据需要 push_back 任意数量的成员。如果效率很重要,请使用保留(或调整大小)。还有一个名为 data() 的成员是为了与 C 兼容(但是 C 不能调用你的向量,至少不容易调用)。

您的代码看起来非常 C-ish。

在 C++ 中执行此操作的惯用方法是:

struct WFSCDMCURRENCYEXP
{
   std::string     cCurrencyID;
   SHORT           sExponent;
};

std::vector<WFSCDMCURRENCYEXP> CdmCurrencies {
    { "ARG", 3 } ,
    { "EUA", 3 } ,
    // lots more countries
};

更新:

我刚刚注意到您显然与 c-style API 互动,并且可能需要以其原始形式使用 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];

我认为您尝试处理 WFS_INF_CDM_CURRENCY_EXP 消息以在您的 CDM 中获取有关货币的信息。

仔细阅读 XFS 规范:

Output Param LPWFSCDMCURRENCYEXP *lppCurrencyExp; Pointer to a NULL-terminated array of pointers to WFSCDMCURRENCYEXP structures

这意味着您必须分配一个指向 WFSCDMCURRENCYEXP 的指针数组,大小为 N+1,并将最后一项设置为空。

在 CEN/XFS 中,您不能使用标准的 new 或 malloc 进行内存分配。 您需要使用 WFMAllocateBuffer 和 WFMAllocateMore 为您 return 调用方的 XFS 结构分配内存。

对于你的任务,你需要这样的东西:

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

用 XFS 操作可没这么简单。它有太多复杂的 API 结构,具有不同的分配规则和数据表示。请仔细阅读 XFS 手册。在第一本书中 ftp://ftp.cen.eu/CWA/CEN/WS-XFS/CWA16926/CWA%2016926-1.pdf 描述了许多概念性的东西。关于配置,内存管理等等。

你的代码不断抛出 WFS_ERR_INTERNAL_ERROR 因为你还没有一个功能齐全的 XFS 环境设置,设置一个正确的配置,或者模拟一个(注册表项,sdk,dll 等)然后再次测试它,使确保您的代码包含正确的 headers 并确保您链接到 msxfs.lib、xfs_conf.lib 和 xfs_supp.lib