C ++ / CLI:返回到非托管对象的引用(C++/CLI: return a reference

2019-11-03 16:49发布

我正在寻找一种方式来参考返回另一个对象,它是一个管理对象中的一员。 这可以在C ++可以容易地实现,但对于C ++ / CLI包装与C#中使用的挑战。 下面是可重复的情况下(这是一个很大的代码,但是这一切都非常简单,只是表明这个问题)

C ++类:

class NATIVEAPI NativeSlave
{
public:
    NativeSlave() : x_( 0 ), y_( 0.0 )
    {}

    NativeSlave( int x, double y ) : x_( x ), y_( y )
    {}

    int x_;
    double y_;
};

class NATIVEAPI NativeMaster
{
public:
    __declspec( property( get = getSlave, put = setSlave ) ) NativeSlave& slave;
    NativeSlave& getSlave()
    {
        return *pSlave; //returns a reference
    }
    void setSlave( const NativeSlave& slave )
    {
        *pSlave = slave;
    }

public:
    NativeMaster() : pSlave( new NativeSlave( 4, 5.0 ) )
    {}
    ~NativeMaster()
    {
        delete pSlave;
    }

private:
    NativeSlave* pSlave;
};

C ++的用法:

NativeSlave slave = NativeSlave( 1, 2.0 ); //now, slave.x==1, slave.y==2.0
NativeMaster master; //now, master.slave.x==4, master.slave.y==5.0

master.slave = slave; //now, master.slave.x==1, master.slave.y==2.0
master.slave.x_ = 6; //now, master.slave.x==6
master.slave.y_ = 10.0; //now, master.slave.y==10.0

因此,在C ++中,我们可以很容易地得到一个基本对象的引用并在它的方法操作(这里,成员公开以简化的例子)。

然后,目标是包裹在C ++ / CLI,以实现在C#相同的功能(使用)如在C ++以上:

C#(需要的话):

ManagedSlave slave = new ManagedSlave(1, 2.0); //now, slave.x==1, slave.y==2.0
ManagedMaster master = new ManagedMaster(); //desired: master.slave.x==4, master.slave.y==5.0

master.slave = slave; //desired: master.slave.x==1, master.slave.y==2.0
master.slave.x = 6; //no appropriate get() method to change master.slave
master.slave.y = 10.0; //no appropriate get() method to change master.slave

下面是编写一个包装的尝试:

C ++ / CLI( 在获取/设置属性的方法有问题 ):

public ref class ManagedSlave
{
public:
    property int x
    {
        int get()
        {
            return mSlave->x_;
        }
        void set( int x )
        {
            mSlave->x_ = x;
        }
    }
    property double y
    {
        double get()
        {
            return mSlave->y_;
        }
        void set( double y )
        {
            mSlave->y_ = y;
        }
    }
public:
    ManagedSlave( int x, double y ) : mSlave( new NativeSlave( x, y ) )
    {}
    ~ManagedSlave()
    {
        delete mSlave;
    }

internal:
    NativeSlave* mSlave;
};

public ref class ManagedMaster
{
public:
    property ManagedSlave^ slave
    {
        ManagedSlave^ get()
        {
            //??????????????????????????
        };
        void set( ManagedSlave^ slave )
        {
            //is this correct???????????
            mMaster->slave.x_ = slave->x;
            mMaster->slave.y_ = slave->y;
        };
    }

public:
    ManagedMaster() : mMaster( new NativeMaster() )
    {}
    ~ManagedMaster()
    {
        delete mMaster;
    }

internal:
    NativeMaster* mMaster;
};

Answer 1:

.NET“引用”一点不像C ++引用。

也有一些是在.NET是一个C ++参考,等效ref有资格参数的关键字。 但是,有没有办法将它用于除参数什么。 (在IL级别可用于局部变量还可以,但仍然没有对返回类型)

在大多数情况下,你可以通过额外的间接层解决这个问题。

你的具体情况,它真的很简单:

ManagedSlave( NativeSlave* s ) : mSlave( s )
{}
~ManagedSlave()
{
    // empty
}

ManagedSlave^ ManagedMaster::slave::get()
{
     return gcnew ManagedSlave( &mMaster->getSlave() );
}

// remove ManagedMaster::slave::set

基本上,没有理由ManagedSlave负责分配和释放一个NativeSlave ,因为NativeMaster已经做到这一点。



文章来源: C++/CLI: return a reference to unmanaged object
标签: c# c++ c++-cli