我试图传递一个结构体,例如:
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的评论是解决我问题的正确答案。但是谢谢你,詹姆斯(和其他人),感谢你投入的时间。
/解决