Как передать List<int> как параметр из C# в C++ CLI?

126
10 января 2021, 02:10

Ну собственно в заголовке и есть вопрос.

У меня есть репозиторий c# который хранит List<int> нужно все это дело передать в c++ CLI

Как это сделать?

Правка

Я использую CLI как адаптер для чистой C++ имплементации. Я передаю из C# List в CLI , CLI его получает конвертирует в vector и вызывает метод из чистого C++ класса. Который естественно ничего не знает о List и знает только как работать с vector

Правка

Вот так выглядит функция в C++ которую нужно вызвать из CLI

int computeMulPlusVals(std::vector<int> const & vect_first, std::vector<int> 
const & vect_second)
{
int result = 0;
int firstVectSize = vect_first.size();
int secondVectSize = vect_second.size();
int size = std::min(firstVectSize, secondVectSize);
for (int i = 0; i < size; i++)
{
    result += vect_first[i] * vect_second[i];
}
return result;
}

Вот функция в CLI

int MathCore_CLI::computeMulPlusVals(List<int>^ list_first, List<int>^ list_second)
{
    auto vec_first = std::vector<int>(list_first->Count);
    for (int i = 0; i < list_first->Count; i++)
    {
        vec_first.at(i) = list_first[i];
    }
    auto vec_second = std::vector<int>(list_second->Count);
    for (int i = 0; i < list_second->Count; i++)
    {
        vec_second.at(i) = list_second[i];
    }
    return m_pMathCore->computeMulPlusVals(vec_first, vec_second);
}

получаю вот такую ошибку

Severity Code Description Project File Line Suppression State Error LNK2028 unresolved token (0A0003A5) "public: int __cdecl MathCore::computeMulPlusVals(class std::vector > const &,class std::vector > const &)" (?computeMulPlusVals@MathCore@@$$FQEAAHAEBV?$vector@HV?$allocator@H@std@@@std@@0@Z) referenced in function "public: int __clrcall MathCore_CLI_namespace::MathCore_CLI::computeMulPlusVals(class System::Collections::Generic::List ^,class System::Collections::Generic::List ^)" (?computeMulPlusVals@MathCore_CLI@MathCore_CLI_namespace@@$$FQE$AAMHPE$AAV?$List@H@Generic@Collections@System@@0@Z) EngineLib_CLI C:\Aleksey\TestDeleteIt\Engine_CLI\MathCore_CLI.obj 1

Answer 1

Как я понял, вы уже сделали передачу списка из C# в C++/CLI.

Осталось сделать трансформацию из List<T> в vector<T>.

Имеем:

using namespace System::Collections::Generic;
List<int>^ list

Просто создаём экземпляр вектора и в цикле добавляем в него элементы:

std::vector<int>* vec = new std::vector<int>();
for each(int n in list) {
    vec->push_back(n);
}

Можно сразу создать вектор нужной длины, чтобы не было переалокаций:

auto vec = new std::vector<int>(list->Count);
for (int i = 0; i < list->Count; i++) {
    vec->at(i) = list[i];
}

Или суть вопроса в том, как избежать лишних копирований?

Answer 2

Я нашел более оптимизированое решение

int MathCore_CLI::computeMulPlusVals(array<int>^ arr_first, array<int>^ arr_second)
{
    auto vec_first = std::vector<int>(arr_first->Length);
    cli::pin_ptr<int> pPinnedFirst = &arr_first[0];
    memcpy(vec_first.data(), pPinnedFirst, arr_first->Length * sizeof(int));
    auto vec_second = std::vector<int>(arr_second->Length);
    cli::pin_ptr<int> pPinnedSecond = &arr_second[0];
    memcpy(vec_second.data(), pPinnedSecond, arr_second->Length * sizeof(int));
    return m_pMathCore->computeMulPlusVals(vec_first, vec_second);
}

по шагам

1) нужно создать вектор 2) захватить его в памяти(чтоб в случае чего сслыки не поменялись) 3) скопировать данные

Это будет намного быстрее по производительности

READ ALSO
некоректо работает Socket сервер

некоректо работает Socket сервер

есть классы 1) Объект состояния сокет-клиента StateObject и 2) сам сервер SocketAsync

114
Получение коллекций из базы данных SQL [закрыт]

Получение коллекций из базы данных SQL [закрыт]

Хотите улучшить этот вопрос? Добавьте больше подробностей и уточните проблему, отредактировав это сообщение

117
Как заполнить radiobutton массивом C# Windows Form

Как заполнить radiobutton массивом C# Windows Form

Есть несколько radioButton пример, (заполнены для примера, нужно случайными через цикл)

101
C# Когда оправдан захват внешних переменных в анонимных методах?

C# Когда оправдан захват внешних переменных в анонимных методах?

В C# предусмотрен механизм захвата внешних переменных в анонимных методахПриведу пример кода:

129