Есть COM компонента. Она реализует
интерфейс
__interface ICKMeansMethod : IDispatch
{
[id(1), helpstring("method Set_Data")] HRESULT Set_Data([in, satype(DOUBLE)] SAFEARRAY * point, [in, satype(DOUBLE)] SAFEARRAY * cluster);
};
(Компонента создана на С++ с помощью ATL).
реализация Set_Data(.....)
STDMETHODIMP CCKMeansMethod::Set_Data(SAFEARRAY * point, SAFEARRAY * cluster)
{
/*
предполагается, что point - NxM мерный массив.
В данном примере я остановился на Nx2.
(N двухмерных точек типа DOUBLE).
2-х мерные - для примера, чтобы не загромождать код.
см. long * aIndex[]
*/
DOUBLE cElement;
if (!point)
return S_OK;
CComSafeArray<DOUBLE> pSar;
pSar.Attach(point);
long dim1 = pSar.GetDimensions();
long dim2 = pSar.GetCount();
long * aIndex = new long [2];
for (int x = 0; x < dim1; x++)
{
for (int y = 0; y < dim2; y++)
{
aIndex[0]=x;
aIndex[1]=y;
ATLASSERT(pSar.MultiDimGetAt(aIndex,cElement) == S_OK);
// Далее творю чего-то с cElement;
}
}
pSar.Detach();
delete [] aIndex;
return S_OK;
}
После, того, когда я добавил Reference на зарегистрированый
компонент, я получил все необходимое (даже отдельно появилась сборка, обеспечивающая
взаимодействие с COM-ой компонентой).
(*)
void ICKMeansMethod.Set_Data(System.Array point, System.Array cluster);
Все бы хорошо, но
я получил следующее — одномерный массив.
Просмотрев полученную сборку с помощью
ildasm.exe я увидел:
instance void Set_Data([in] class [mscorlib]System.Array marshal( safearray float64) point,
[in] class [mscorlib]System.Array marshal( safearray float64) cluster) runtime managed internalcall
{
}
Как можно передать 2-й массив в (*)?
В С++, Delphi есть такая вещь,как SafeArrayCreate, в которую можно передать размерность массива.
Как это можно сделать в C#?
Одномерный
double [] pnt = new double[3];
передается. Но как-то очень странно.
Он, как и полагается (по смыслу) одномерный, но все элементы его почему-то всегда
равны 1-му элементу массива.
Передать double[][] не получается — Exception
System.Runtime.InteropServices.SafeArrayTypeMismatchException: Specified array was not of the expected type.
at CKMeans.CCKMeansMethodClass.Set_Data(Array point, Array cluster)
Как это сделать? Уже весь INet облазл.
Помогите плиз
И еще.
Кто нибудь знает, чем отличается генерация кода на С++ с
Multi-threaded Debug DLL (/MDd)
и
Multi-threaded DLL (/MDd).
Ибо с 1-й из SAFEARRAY данные читаются нормально (параметры размерности, данные, а во 2-м случае
считывается только мусор, но размерность массива определяется)
Хелп, плиз.
Здравствуйте, Аноним, Вы писали:
А>http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpguide/html/cpconDefaultMarshalingForArrays.asp
А>Оно?
А>
данное сообщение получено с www.gotdotnet.ru
А>ссылка на оригинальное сообщение
Не совсем. Там не говорится, как передать многомерный массив.
Есть пример про передачу одномерного.
Но продлема в том, что при
просмотре полученной сборки при импортировании
ildasm.exe я увидел:
instance void Set_Data([in] class [mscorlib]System.Array marshal( safearray float64) point,
[in] class [mscorlib]System.Array marshal( safearray float64) cluster) runtime managed internalcall
{
}
Т.е. есть System.Array
Но если
написать (делаем массив 3х3)
CKMeans.ICKMeansMethod ck = new CKMeans.CCKMeansMethodClass();
double [][] info = new double[3][];
info[0] = new double[] {1, 2, 3};
info[1] = new double[] {1, 2, 3};
info[2] = new double[] {1, 2, 3};
ck.Set_Data(info, null);
То будет Exception:
System.Runtime.InteropServices.SafeArrayTypeMismatchException: Specified array was not of the expected type.
at CKMeans.CCKMeansMethodClass.Set_Data(Array point, Array cluster)
Здравствуйте, D.Triton, Вы писали:
Для выделения кода следует пользоваться соответствующими тегами, иначе его очень тяжело читать
... << RSDN@Home 1.1.4 beta 3 rev. 268>>
Здравствуйте, D.Triton, Вы писали:
DT>Одномерный
DT> double [] pnt = new double[3];
DT>передается. Но как-то очень странно.
DT>Он, как и полагается (по смыслу) одномерный, но все элементы его почему-то всегда равны 1-му элементу массива.
DT>Передать double[][] не получается — Exception
DT> System.Runtime.InteropServices.SafeArrayTypeMismatchException: Specified array was not of the expected type.
DT> at CKMeans.CCKMeansMethodClass.Set_Data(Array point, Array cluster)
DT>Как это сделать? Уже весь INet облазл.
DT>Помогите плиз
А если не double[][], а double[,] ? Насколько я знаю, SAFEARRAY вовсе не явлется "Jagged Arrays", чем является запись double[][].