Вызов неуправляемого кода из C# и получение массива.

vlsaf
Дата: 16.04.2014 19:24:22
Есть некая dll и в ней нужная функция.
Функция принимает некий одномерный массив A типа double и размерностью N.
var A = new double[N];

А возвращает другой массив B и той размерности, которой сочтет нужным. Т.е. заранее выделять память под массив B я не могу.
double[] B;
- и больше ничего мне не известно!

Вопрос, как в функцию передать ссылку на массив B и после выполнения получить в C# полноценный массив?
[SuppressUnmanagedCodeSecurity]
internal static class MyFunkNative
{
    [DllImport("MyDll", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true, SetLastError = false)]
    internal static extern int MyFunk(
          [In] double[] A
        , [Out] double[] B
        );
}


Как использовать это не понятно. Если я пишу так:
var ret = MyFunkNative.MyFunk(A, B);

то студия говорит, что В перед использованием должно быть инициализировано. Как то надо через ссылки сделать. Но вот как?
YUBA
Дата: 16.04.2014 19:42:17
Недавно делал такое с чужой аналогичной функцией возвращающей Double массив. Все проходило без проблем.
М.б. сигнатуру помtнять на С# типа f(double[] a[], out double[] B). В C# [out] в скобках не катит.
Можно попробовать f(double[] a[], ref double[] B).
YUBA
Дата: 16.04.2014 19:44:02
Сорри, ошибся, после а [] конечно же не надо.
vlsaf
Дата: 16.04.2014 20:01:47
YUBA
Недавно делал такое с чужой аналогичной функцией возвращающей Double массив.

Ты этот массив перед вызовом как-то инициализировал? Можно кусок кода?
YUBA
Дата: 16.04.2014 20:26:41
vlsaf
Ты этот массив перед вызовом как-то инициализировал? Можно кусок кода?
Нет, не инициализировал.
DLL цепляется по Референс, т.е. сигнатуры не надо. Кусок примерно такой.
double[] A; // =new double[] - это вроде не надо
A= f1(<список параметров>);
// была и такая
f2(<список параметров>, A); // там точно было в описании f2(<список параметров>,out double[] Data)
Собственно, и кода больше нет. Как то так.
C Double не нашел. Нашел подобное, но только со String
String[] SDataArr;
SDataArr = TStr.Split(SS, StringSplitOptions.RemoveEmptyEntries);
vlsaf
Дата: 16.04.2014 21:02:13
YUBA, точно! Спасибо. Я что-то затупил. Вот код, который ошибки синтаксиса не дает.
public static class MyFunkNative
{
    public static void Start(ref double[] a, out double[] b)
    {
        MyFunk(a, out b);
    }


    [DllImport("FuncDll.dll", CharSet = CharSet.Auto)]
    private static extern void MyFunk([In] double[] a, [Out] out double[] b);
}


Завтра на работе проверю на работоспособность.
vlsaf
Дата: 17.04.2014 11:34:47
Не получилось.

В с++ память под массив выделяется. Массив заполняется нужными значениями (коллега выводит на консоль результаты). А вот при передаче массива обратно в C# лезет ошибка "Попытка чтения или записи в защищенную память.".
SolYUtor
Дата: 17.04.2014 13:13:57
vlsaf,

точную сигнатуру неуправляемой функции в студии.
vlsaf
Дата: 17.04.2014 13:45:14
Да там ничего сложного. На С++ такое вот описалово.
int MyFunk(double *A, double *В)
vlsaf
Дата: 17.04.2014 14:36:46
Не. Наврал. Там такая сигнатура:
double MyFunk(double *A, double **B)
{
 *B = (double *)malloc(10*sizeof(double));
 printf("Memory for 'B' was allocated...\n\n");

 for (int i = 0; i < 10; i++) {  (*B)[i] = (double)i*2; }
 for (int i = 0; i < 10; i++) {   printf("B: %f\n", (*B)[i]); }
 return 0;
}


Для примера заполняется массив И значениями и выводится на экран