2017-01-05 2 views
0

Я изучаю C++ и кажется, что невозможно получить массив как возвращаемый тип. Это правда?Не может быть массив как возвращаемый тип в C++? Альтернативы?

int foo(){} 

работает отлично, но

int[] foo(){} 

нет. Какова общепринятая работа вокруг этого?

В настоящее время я работаю над проектом, который использует как C#, так и C++. У меня есть C# файл, доступ к некоторым DLL код:

[DllImport("Test.dll")] 
public static extern byte[,] getBytes(
    [In] string filePath, 
    [In] string dataGroup); 

Мой заголовочный файл имеет:

TEST_DLL BYTE[][] getBytes(std::string filePath, std::string dataGroup); 
/* This throws an error since I can't use an array as a return type. */ 

и моей реализации внутри файла .cpp является:

TEST_DLL BYTE[][] getBytes(std::string filePath, std::string dataGroup) 
{ 
    printf("getBytes entered." 

    /* More code here...*/ 
} 

/* This also throws an error due to the array use. */ 

В основном, Я пытаюсь вернуть массив двумерных байтов из моего DLL-кода без необходимости конвертировать что-либо со стороны C#, т. Е. Все выполнение кода, связанное с getBytes, должно происходить в коде C++.

У меня есть рабочий пример этого, который не использует массив, а скорее void *, который из моего понимания является указателем на массив, который я возвращаю. Затем у меня есть функция C#, которая использует IntPtr и Marshal.Copy для получения байтового массива. Я пытаюсь определить разницу в затратах между этими двумя методами. Я бы предположил, что было бы намного быстрее возвращать массив двумерных байтов непосредственно из кода на C++ вместо использования дополнительного кода преобразования C# (используемые множители данных огромны - около 500 ГБ, так что каждая небольшая часть оптимизации рассчитывается).

Как я могу получить двумерный массив байтов только из моего кода на C++ без необходимости его преобразования в C#?

+0

int * foo() {} будет работать – Steve

+0

В C++, поскольку * вы * не можете вернуть массив, используйте 'std :: vector'. –

+0

Это не собирается вмешиваться в C#, хотя, я не думаю? –

ответ

2

У вас есть два отдельных вопроса:

  1. Возвращение массива из функции C/C++ (метод)

  2. взаимодействующими с C#.

Существует ряд решений для выпуска №1. Вероятно, лучше всего вернуть вектор (если вы хотите скопировать данные) или ссылку на вектор (если у вас есть возвращаемое значение, которое останется навсегда)). Вы также можете передать ссылку на вектор в качестве параметра и заполнить вектор в вашей функции.

Проблема №2: массив C# не является нативным типом данных на C++, поэтому вам понадобится специальный целевой код для «маршалирования» данных в соответствующий тип C#. См. this question для более подробной информации.

+0

Есть ли способ устранить необходимость маршалирования данных? – Roka545

+1

Существуют определенные критерии, необходимые для того, чтобы что-то было массивом C#. Если они не выполняются, это не массив C#, и если вы попытаетесь использовать его в качестве одного из самых неприятных вещей. Очевидно, есть способы передать информацию из C++ в C#, которая не включает в себя Marshaling данных в массив. На самом деле, похоже, что вы обнаружили один из них: IntPtr позволяет C# получать доступ к исходным данным типа C++. Однако, независимо от того, какой подход вы используете, вам нужно будет написать (или использовать существующий) код с одной стороны или другого интерфейса, чтобы справиться с различными моделями памяти, используемыми C++ и C#. –

+2

Может быть один способ, если размер массива известен. Затем вы можете создать его на C# и отправить его как параметр в C++. См. Также [Маршалские массивы с использованием pinvoke] (https://msdn.microsoft.com/en-us/library/bd99e6zt.aspx) для разных способов сделать это. –