Как выполняется сортировка при вызове кода C ++ из C ++ / CLI?

Согласно этому вопросу можно беспрепятственно комбинировать управляемый и неуправляемый код с использованием C ++ / CLI. Я не совсем понимаю - разве не должно быть разделения между управляемым и неуправляемым?

Например, у меня есть InnerLibrary, который скомпилирован как нативный C ++ .dll с опубликованным заголовком, и C ++ / CLI OuterLibrary, который вызывает код из внутренней библиотеки. Будет ли сортировка? Кто это осуществит и насколько это будет дорого?

9
задан Community 23 May 2017 в 12:09
поделиться

6 ответов

Никакого маршалинга не требуется, потому что C ++ / CLI может генерировать небезопасный код, который выполняет вызов напрямую. Взгляните на код C ++ / CLI в Reflector - он будет сильно отличаться от C #.

Это то, что C # не может сделать (по крайней мере, не без ключевого слова unsafe и некоторых хаков с указателями), а также то, что C ++ / CLI в чистом режиме не может сделать (для по той же причине, что и C #).

Небезопасный код .NET может выполнять прямые вызовы неуправляемых функций; просто эта возможность доступна только через C ++ / CLI.

3
ответ дан 4 December 2019 в 14:26
поделиться

Маршалинг - это процесс передачи неуправляемых данных или вызовов в управляемый мир. Это просто, так сказать, перевод между ними.

С помощью C ++ / CLI вы можете смешивать и сопоставлять. Это означает, что если вы используете свою библиотеку напрямую, используя файл * .h и используя традиционный код C ++, она будет неуправляемой и без маршалинга. Если вы обращаетесь к этим данным с помощью классов BCL или собственного управляемого кода, вы добавляете уровень маршалинга вручную, но только при необходимости. То есть LPTSTR необходимо будет преобразовать в управляемую строку, чтобы использовать ее как единое целое. Используя C ++ / CLI, вы можете пропустить этот шаг и придерживаться традиционного кода C ++, создавая более быстрый и гибкий код за счет отказа от безопасного, проверенного управляемого кода.

3
ответ дан 4 December 2019 в 14:26
поделиться

Ну, это функция, встроенная в компилятор C ++ / CLI, которая называется C ++ Interop. Как вы думаете, здесь гораздо меньше черной магии. Компилятор JIT генерирует тот же машинный код, что и ваш компилятор C ++. Все типы значений .NET имеют прямой эквивалент в C ++, поэтому преобразование не требуется. Он не автоматически обрабатывает ссылочные типы, вы должны сделать это самостоятельно. pin_ptr <>, обычно.

Все, что он на самом деле , - это вводит немного кода, который обрабатывает переход от кадра управляемого стека к кадру неуправляемого стека. Этот код помещает в стек специальный «cookie», который распознается сборщиком мусора. Это предотвращает его грубое попадание в неуправляемые фреймы и неправильную идентификацию неуправляемых указателей как объектных ссылок. В этом коде не так много всего, на сборку Release требуется около 5 наносекунд, плюс-минус.

6
ответ дан 4 December 2019 в 14:26
поделиться

Здесь есть два момента:

1) Управляемый / неуправляемый переход кода: каждый переход имеет фиксированную стоимость. Когда код C ++ / CLI компилируется в единую сборку, компилятор пытается сделать весь код управляемым, когда это возможно, чтобы минимизировать такие переходы. При вызове внешней неуправляемой Dll из кода C ++ / CLI такая оптимизация невозможна. Поэтому рекомендуется минимизировать такие переходы, по крайней мере, в критических по времени участках. Подробнее об этом см. Здесь: http://msdn.microsoft.com/en-us/magazine/dd315414.aspx , Производительность и расположение границы взаимодействия

2) Маршаллинг параметров. Это зависит от типа параметров. Некоторые параметры не нужно упорядочивать, например, простые типы, такие как int. Строки должны быть выстроены. Некоторые приемы, такие как закрепление указателей, позволяют предотвратить маршалинг массива простых типов.

0
ответ дан 4 December 2019 в 14:26
поделиться

Это зависит от типов данных.

Внутренние типы, такие как int, double и так далее (string не подходит), имеют одинаковое представление как в родном, так и в управляемом коде, маршалинг не требуется. Массивы внутренних типов также размещаются одинаково (если игнорировать метаданные, которые хранит .NET, но они отделены от содержимого массива).

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

Если данные хранятся в объекте на управляемой куче, может потребоваться пиннинг (это справедливо для всех массивов).

Типы классов, с другой стороны, должны быть преобразованы/переведены туда и обратно.

0
ответ дан 4 December 2019 в 14:26
поделиться

Маршаллинг присутствует, но вы (т.е. программист) должны сделать это явно.

Если ваша внешняя библиотека C++CLI вызывает функцию, которая принимает System.String/System::String^, система типов C++ требует, чтобы вы выполнили преобразование типа перед передачей ее в функцию внутренней библиотеки, которая принимает const char*. Вы должны выполнить преобразование самостоятельно - это и есть маршаллинг.

Microsoft поставляет нечто под названием C++ Support Library, которая предоставляет функции, помогающие взаимодействию C++ <-> C++CLI.

2
ответ дан 4 December 2019 в 14:26
поделиться
Другие вопросы по тегам:

Похожие вопросы: