2014-12-13 3 views
-1

Я использую C# и C++ dll. Я хочу отправить массив из C++ в C#. Я хочу вернуться из массива C++ с 512 удвоениями. В коде C++ он работает отлично. У меня есть результаты точно, что я ожидал в массиве double.Преобразование данных из C++ dll в C#

Позже я отправляю данные с C++ на C# и преобразую эти данные в массив double в C#. Первые 450 элементов из C++ перемещаются в массив на C# без каких-либо ошибок. Но левые двойники странные, и у них нет ничего общего с входными данными.

Я не знаю, почему именно в 450 элементах начинается с удвоением до конца.

EDIT. Также та же проблема, когда я смену массивов в C++ и C# на float, а также при анализе данных на целое.

C# код.

[DllImport(@"C:\Users\Jaryn\Documents\Visual Studio 2013\Projects\MathFuncDll\Debug\MathFuncDll.dll", CallingConvention = CallingConvention.Cdecl)] 
public static extern IntPtr One(string address); 

static void Main(string[] args) 
{ 
    var pointer = One(@"C:\Users\Jaryn\Documents\101_ObjectCategories\accordion\image_0002.jpg"); 
    var result = new double[512]; 
    Marshal.Copy(pointer, result, 0, 512); 
    foreach (var x in result) 
    { 
     Console.WriteLine(x + " "); 
    } 
} 

MathFuncsDll.h

#include <stdexcept> 
using namespace std; 

namespace MathFuncs 
{ 
    extern "C" { __declspec(dllexport) double* One(char* str); } 
} 

MathFuncsDll.cpp

double* One(char* adress) 
{ 

    IplImage* img = cvLoadImage(adress, CV_LOAD_IMAGE_COLOR); 

    double data[512]; 
    int iteration = 0; 

    ...  

    for (int h = 0; h <h_bins; h++) 
    { 
     for (int s = 0; s < s_bins; s++) 
     { 
      double bin_value = 0; 
      for (int v = 0; v < h_bins; v++) 
      { 
       bin_value += cvGetReal3D(hist->bins, h, s, v); 
       data[iteration] = bin_value; 
       iteration++; 
      } 
     } 
    } 

    ... 


    return data; 
} 
+0

Довольно уверен, что вы должны заменить 'Marshal.Copy (pointer, result, 0, 512)' с 'Marshal.Copy (указатель, результат, 0, 512 * sizeof (double))' – SimpleVar

+0

Необработанное исключение типа 'System .ArgumentOutOfRangeException 'произошел в mscorlib.dll Дополнительная информация: Запрошенная область действия за пределами массива. – Jaryn

+0

О, возможно, что перегрузка характерна для двойного. – SimpleVar

ответ

2

Ваша проблема заключается в том, что вы возвращаете адрес локальной переменной. Как только функция вернется, жизнь локальной переменной заканчивается. И поэтому адрес, который вы возвращаете, является адресом объекта, жизнь которого окончена.

Чистый способ сделать это, чтобы вызывающий абонент выделил массив и заложил его. Попросите абонента передать адрес первого элемента массива и длину массива. Тогда вызываемый может быть уверен, что не должен писать за пределами массива.

Смежные вопросы