【问题标题】:What does "pin a native member" mean?“固定本地成员”是什么意思?
【发布时间】:2013-09-25 05:04:47
【问题描述】:

我在 MSVS 2010 下编译某些代码时遇到问题,并且出现 C2678 错误。我在这里找到了该错误的描述:

http://msdn.microsoft.com/en-us/library/ys0bw32s(v=vs.100).aspx

但我不明白“固定本地成员”是什么意思。

谁能解释一下?

这是产生该错误的部分代码:

#pragma once

#include <functional>
#include <vector>
#include <memory.h>

template<typename callbackCodes_e, callbackCodes_e endOfCodes, typename param_t>
class CCallbackContainer
{
    typedef std::function<void(param_t)> callback_t;

public:
    struct callbackInfo_t
    {
        callbackCodes_e code;
        callback_t callback;
        param_t param;
        size_t countdownToAutoDelete;
    };

    CCallbackContainer() {};
    ~CCallbackContainer() {};

    typedef std::function<void(param_t)> callback_t;
    typedef callbackInfo_t HANDLE;

    std::vector<callbackInfo_t> m_Callbacks[endOfCodes];
    void callbackCall(callbackInfo_t const & callbackInfo);

public:
    inline bool validCode(callbackCodes_e code) { return code < endOfCodes; }

    HANDLE callbackSet(callbackCodes_e code, callback_t callback, DWORD param, size_t countdownToAutoDelete = 1);
    void callbackClear(HANDLE callbackToRemove);
    void callbackCall(callbackCodes_e code)
    {
        auto callbackList = m_Callbacks[code];
        for(auto i: callbackList)
        {
            i->callback(i->param);
        }
        for_each(auto i = callbackList.rbegin(); i != callbackList.rend(); ++i)
        {
            if (--(i->countdownToAutoDelete) < 1)
            {
                callbackList.erase(i);
            }
        }
    }
};

// template implimentation has to be in header file
template<typename callbackCodes_e, callbackCodes_e endOfCodes, typename param_t>
typename CCallbackContainer<callbackCodes_e, endOfCodes, param_t>::HANDLE // return
    CCallbackContainer<callbackCodes_e, endOfCodes, param_t>::callbackSet // function name
        (callbackCodes_e code, callback_t callback, DWORD param, size_t countdownToAutoDelete) // parameters
{
    ASSERT(validCode(code));
    callbackInfo_t callbackInfo = { code, callback, param, countdownToAutoDelete };
    ASSERT(std::find(m_Callbacks[code].begin(), m_Callbacks[code].end(), callback) == m_Callbacks[code].end());
    m_Callbacks[code].push_back(callbackInfo);
    return callbackInfo;
}

template<typename callbackCodes_e, callbackCodes_e endOfCodes, typename param_t>
void // return type
    CCallbackContainer<callbackCodes_e, endOfCodes, param_t>::callbackClear // function name
        (typename CCallbackContainer<callbackCodes_e, endOfCodes, param_t>::HANDLE callbackToRemove) // parameters
{
    callbackCodes_e code = callbackToRemove.code;
    ASSERT(validCode(code));
    auto iCallbackInfo = std::find(m_Callbacks[code].begin(), m_Callbacks[code].end(), callbackToRemove);
    ASSERT(iCallbackInfo == m_Callbacks[code].end());
    m_Callbacks[code].erase(iCallbackInfo);
}

template<typename callbackCodes_e, callbackCodes_e endOfCodes, typename param_t>
void // return type
    CCallbackContainer<callbackCodes_e, endOfCodes, param_t>::callbackCall // function name
        (callbackInfo_t const & callbackInfo) // parameters
{
    callbackInfo.callback(callbackInfo.param);
    if (--callbackInfo.countdownToAutoDelete < 1)
    {
        callbackClear(callbackInfo);
    }
}

template<typename callbackCodes_e, callbackCodes_e endOfCodes, typename param_t>
void // return type
    CCallbackContainer<callbackCodes_e, endOfCodes, param_t>::callbackCall // function name
        (callbackCodes_e code) // parameters
{
    auto callbackList = m_Callbacks[code];
    for(auto i: callbackList)
    {
        i->callback(i->param);
    }
    for_each(auto i = callbackList.rbegin(); i != callbackList.rend(); ++i)
    {
        if (--(i->countdownToAutoDelete) < 1)
        {
            callbackList.erase(i);
        }
    }
}

该错误实际上是由算法中的某些东西产生的:

14>c:\program files (x86)\microsoft visual studio 10.0\vc\include\algorithm(41): error C2678: binary '==' : no operator found which take a left-hand operand of type 'CCallbackContainer:: callbackInfo_t'(或没有可接受的转换) 14> 与 14> [ 14> callbackCodes_t=CballoonHelp::callbackCodes_t, 14> endOfCodes=eCallbackEnd, 14> 参数_t=DWORD 14>] 14> 可以是“内置 C++ 运算符==(std::_Bool_type, std::_Bool_type)” 14> c:\program files (x86)\microsoft visual studio 10.0\vc\include\functional(277): 或 'bool std::tr1::operator ==(std::tr1::_Unutterable,const std:: tr1::function &)' [使用参数相关查找找到] 14> 与 14> [ 14> 参数_t=DWORD, 14> _Fty=空(双字) 14>] 14> c:\projects\cv-7646\og50\include\gxcoll.h(67): 或 'BOOL operator ==(const GXNDX &,const GXNDX &)' [使用参数相关查找找到] 14> c:\program files (x86)\microsoft sdks\windows\v7.0a\include\guiddef.h(192): or 'int operator ==(const GUID &,const GUID &)' [使用参数找到-依赖查找] // ... 与签名不匹配的其他 operator==() 测试。

在我看来,callbackInfo_t 的默认运算符 ==() 存在问题,但我不确定原因。

【问题讨论】:

  • 我认为这仅适用于 C++/CLI,而不适用于 C++,并且 Microsoft 只是出于实现和文档目的将它们混为一谈。但我不完全确定,C++ 也可能以我不熟悉的方式存在同样的问题。

标签: c++ visual-studio


【解决方案1】:

固定是 C++.NET 中使用的一个术语。当引用类(使用ref class 声明的类)需要访问一些本机成员变量时使用它,您必须 pin 它因为托管引用可以在内存中移动,但本机指针必须呆在固定的地方。一旦你 pin 成员变量你得到一个本地指针,一切正常。当对象unpinned时,它将再次可移动。有关更多详细信息,请搜索pin_ptr&lt;&gt; 模板。

但是您的代码根本没有任何ref class,所以pinning 注释只是在误导您!

您的问题只是您没有为您的callback_t 结构提供operator==()

只需这样做,或者更适合您的情况:

 struct callbackInfo_t
    {
        callbackCodes_e code;
        callback_t callback;
        param_t param;
        size_t countdownToAutoDelete;

        bool operator==(const callbackInfo_t &o) const
        {
           return code == o.code && callback == o.callback &&
                  param == o.param && countdownToAutoDelete == o.countdownToAutoDelete;
        }
    };

但请注意,显然,您比较的任何成员变量也必须具有可比性,否则代码将再次失败并显示类似消息。

【讨论】:

  • 我发的代码中确实没有把它放进去,但是当我做了一个类似的函数时,我仍然得到了同样的信息。事实上,这是我做的第一件事。不过感谢您的澄清。
  • 没有 "C++.NET" 这样的东西。固定也与任何特定语言无关。这是在压缩垃圾收集器的上下文中从本机代码访问托管对象所需的概念。
  • @IInspectable:实际上,它被称为 C++/CLI,是用于 .NET 框架的 C++ 的 MS 方言(我应该说 CLI 吗?)。关于 pinning,是的,它是一个概念,但在 C2678 的上下文中,它显然是指在 C++ 中使用pin_ptr
猜你喜欢
  • 2013-05-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-01-20
  • 1970-01-01
  • 2011-02-16
  • 1970-01-01
  • 2011-10-28
相关资源
最近更新 更多