如何在c++中(非cli)将自定义结构体传递给_variant_t



我试图传递一个结构体,例如:

struct SVec3
{
public:
    float X;
    float Y;
    float Z;
};

放入_variant_t中,以将其存储在SAFEARRAY中。我的方法是首先创建一个实例:

SVec3 rot;
rot.X = 0.1f;
rot.Y = 0.65f;
rot.Z = 0.01f;

然后我通过引用把它放入_variant_t

_variant_t var((IUnknown*)&rot, true);

存储在SAFEARRAY:

LONG index = 0;
SAFEARRAY* psaArgs = SafeArrayCreateVector(VT_VARIANT, 0, 1);
SafeArrayPutElement(psaArgs, &index, &var);  // This throws a memory access exception.

我错在哪里?还有别的办法吗?如果是这样,我应该如何将这些结构的SAFEARRAY传递到SAFEARRAY中?有一个共同的方法吗?或者我错过了像Recorddescription这样的东西,因为这样SAFEARRAY不包含数据,它包含指向数据的指针。但是如何在SAFEARRAY中存储数据呢?

问候Nem

您正在将SVec3指针转换为指向IUnknown接口的指针。您的数据结构是一种简单的数据类型,而不是实现IUnknown的成熟类。因此,一旦Windows试图调用IUnknown上的方法,您的应用程序就会中断。

一些快速谷歌显示一些链接可能对变体和用户定义的类型有用:

  • http://social.msdn.microsoft.com/forums/en/vclanguage/thread/38dca037 - f6da - 43 - dc - 8 fa3 - 0358638681 - ce
  • http://msdn.microsoft.com/en-us/library/ms221039 (VS.85) . aspx
  • http://msdn.microsoft.com/en-us/library/ms221210 (VS.85) . aspx
  • 特别为您:传递udt的安全数组:http://msdn.microsoft.com/en-us/library/ms221212(VS.85).aspx
  • http://msdn.microsoft.com/en-us/library/ms221543 (VS.85) . aspx

您必须首先将您的UDT放入类型库中…

长篇大论。我不想将我的程序集注册为COM对象(这将违背我对该项目的要求),所以我必须避免COM的东西。为此,我做了一个变通。这里有一个例子来说明(c#汇编代码):

[EditorBrowsable(EditorBrowsableState.Never)]
    public float[] INTEROP_Position
    {
        [return: MarshalAs(UnmanagedType.SafeArray, SafeArraySubType = VarEnum.VT_R4)]
        get { return (float[])this.Position; }
        [param: MarshalAs(UnmanagedType.SafeArray, SafeArraySubType = VarEnum.VT_R4)]
        set { this.Position = (DataTypes.Vec3)value; }
    }
    // Inside the Vec3 Definition:
    public static explicit operator Vec3(float[] arr)
    {
        if (arr.Length != 3) throw new Exception("The array must have a length of 3.");
        return new Vec3(arr[0], arr[1], arr[2]);
    }
    public static explicit operator float[](Vec3 vec3)
    {
        return new float[] { vec3.X, vec3.Y, vec3.Z };
    }

在c++端,我手工编组

_variant_t Convert::svec3tovar(SVec3 vec) {
    LONG index = 0;
    SAFEARRAY* psaStruct = SafeArrayCreateVector(VT_R4, 0, 3);
    SafeArrayPutElement(psaStruct, &index, &vec.X);
    index = 1;
    SafeArrayPutElement(psaStruct, &index, &vec.Y);
    index = 2;
    SafeArrayPutElement(psaStruct, &index, &vec.Z);
    VARIANT vV ;
    vV.vt = VT_ARRAY | VT_R4;
    vV.parray = psaStruct;  
    return _variant_t(vV);
}

SVec3 Convert::vartosvec3(_variant_t var) {
    SVec3 vec;
    SAFEARRAY* psaStruct = var.parray;
    LONG index = 0;
    SafeArrayGetElement(psaStruct, &index, &vec.X);
    index = 1;
    SafeArrayGetElement(psaStruct, &index, &vec.Y);
    index = 2;
    SafeArrayGetElement(psaStruct, &index, &vec.Z);
    return vec;
}

效果很好。没有COM的东西。:)

我知道真正的答案是詹姆斯给出的,但为了避免COM,这是我的答案。也许user786653的评论是解决我问题的正确答案。但是谢谢你,詹姆斯(和其他人),感谢你投入的时间。

/解决

相关内容

  • 没有找到相关文章

最新更新