1

我正在尝试传递一个结构,例如:

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 中?

问候内姆

4

2 回答 2

3

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

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

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

于 2011-08-02T15:07:21.430 回答
0

漫长的话题,漫长的一天。我不想将我的程序集注册为 COM 对象(这将违反我对该项目的要求),所以我必须避免使用 COM-Stuff。为此,我做了一个解决方法。下面是一个示例来说明这一点(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 的评论是解决我的问题的正确答案。但是感谢詹姆斯(和其他人)投入的时间。

/解决了

于 2011-08-02T21:50:42.467 回答