unsafe c#

vlsaf
Дата: 22.04.2014 14:43:56
Это развитие вот этой темы.
Изопропил
extern  "C" __declspec(dllexport) void __stdcall   MyFunc(int*sz, double ** p){
	// ну для примера
	*sz= 4;
	*p= static_cast<double*>(:: CoTaskMemAlloc((*sz)*sizeof(double)));	
	for (int i=0;i<*sz;i++) (*p)[i]=i;	
}


+
    public unsafe class Tst
    {
        [DllImport(@"C:\data\TEST\Win32Project2\Debug\Win32Project2.dll")]
        public static extern int MyFunc(out int sz, out double * p);

        public   static double* test()
        {
            int sz;
            double* d;
            MyFunc(out sz, out d);
            double s=0;
            for (int i = 0; i < sz; i++) s += d[i];
            return d;                                 
    }

    public unsafe class Tst1
    {
        [DllImport(@"C:\data\TEST\Win32Project2\Debug\Win32Project2.dll")]
        public static extern int MyFunc(out int sz, out IntPtr  p);

        public   static IntPtr test()
        {
            IntPtr p;
            int sz;            
            MyFunc(out sz, out p);
            double* d = (double*)p.ToPointer();
            double s=0;
            for (int i = 0; i < sz; i++) s += d[i];
            return p;                       
    }

Поехали вопросы:
Зачем этот цикл?: for (int i = 0; i < sz; i++) s += d[i].
Нужно, чтобы метод Test возвратил массив L типа double.
Если я напушу вот так:
public static int Test(out double[] L)
{
            IntPtr p;
            int sz;            
            var info = MyFunc(out sz, out p);
            double* L = (double*)p.ToPointer();
            return info; 
}

Это нормально?
vlsaf
Дата: 22.04.2014 14:53:15
Нет. Не нормально. Указатели могут быть использованы только в контексте unsafe. Как же поиметь массив L?
Алексей К
Дата: 22.04.2014 15:08:21
Не надо unsafe...

[DllImport(@"C:\data\TEST\Win32Project2\Debug\Win32Project2.dll")]
public static extern int MyFunc(out int sz, out IntPtr p);

..........

int sz;
IntPtr p;
MyFunc(out sz, out p);

var a = new double[sz];
Marshal.Copy(p, a, 0, sz);

Marshal.FreeCoTaskMem(p);
Алексей К
Дата: 22.04.2014 15:17:31
Если на С-стороне использовать COM Safe Array, на C#-стороне всё упростится.

Маршалинг по умолчанию для массивов
Изопропил
Дата: 22.04.2014 15:20:58
vlsaf
Нет. Не нормально. Указатели могут быть использованы только в контексте unsafe. Как же поиметь массив L?

пометь все свои классы unsafe
Изопропил
Дата: 22.04.2014 15:21:29
Алексей К,

в библиотеке - malloc , не выйдет
Изопропил
Дата: 22.04.2014 15:21:58
Алексей К,

топикстартеру нужно без копирования
Изопропил
Дата: 22.04.2014 15:23:15
vlsaf
Зачем этот цикл?: for (int i = 0; i < sz; i++) s += d[i].

просто так для примера
Алексей К
Дата: 22.04.2014 15:26:15
Изопропил
Алексей К,

топикстартеру нужно без копирования
Если выделять память под массив на дотнетной стороне, полагаю, копирования не будет?

var a= new double[123];
MyCFunc(a);

?
Изопропил
Дата: 22.04.2014 15:28:02
Алексей К
Если выделять память под массив на дотнетной стороне, полагаю, копирования не будет?

предлагалось - не годится (Создание одномерного массива типа double размерности N)