Длинная тема, длинный день. Я не хочу регистрировать свою сборку как COM-объект (это противоречит моим требованиям для этого проекта), поэтому я должен избегать этого COM-Stuff. Для этого я сделал обходной путь. Вот пример, чтобы проиллюстрировать это (C # Assemblycode):
[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, это мой ответ. Возможно, комментарий user786653 был правильным ответом для решения моей проблемы.
Но спасибо Джеймс (и другим) за потраченное время.
/ решаемые