漫长的话题,漫长的一天。我不想将我的程序集注册为 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 的评论是解决我的问题的正确答案。但是感谢詹姆斯(和其他人)投入的时间。
/解决了