0

我需要将多个值传递给内存,我需要将不同的国家/地区设置为 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();
}
}
4

5 回答 5

3

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

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

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

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

更新:

我刚刚注意到您显然与 c 风格的 API 交互,并且struct可能需要以其原始形式使用它。
尽管在 c++ 中,您仍然可以使用 astd::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];
于 2017-02-20T16:01:23.687 回答
1

声明一个数组:

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而不是,但如果你这样做了,你就不能使用 memcpy,而且跨 DLL 边界char [3]传递 a 可能不是一个好主意。std::string

于 2017-02-20T15:47:52.447 回答
0

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

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

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

于 2017-02-20T16:00:35.547 回答
0

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

仔细阅读 XFS 规范:

输出参数 LPWFSCDMCURRENCYEXP *lppCurrencyExp; 指向以 NULL 结尾的指向 WFSCDMCURRENCYEXP 结构的指针数组的指针

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

在 CEN/XFS 中,您不能使用标准的 new 或 malloc 进行内存分配。您需要使用 WFMAllocateBuffer 和 WFMAllocateMore 为返回给调用者的 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中描述了许多概念性的东西。关于配置、内存管理等。

于 2017-02-20T19:49:05.193 回答
0

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

于 2017-05-10T17:12:40.123 回答