Есть 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-м случае
считывается только мусор, но размерность массива определяется)
Хелп, плиз.