Как выполняется сортировка, когда код C ++ вызывается из C ++ / CLI? - PullRequest
9 голосов
/ 16 августа 2010

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

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

Ответы [ 6 ]

6 голосов
/ 16 августа 2010

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

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

3 голосов
/ 16 августа 2010

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

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

3 голосов
/ 16 августа 2010

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

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

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

2 голосов
/ 16 августа 2010

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

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

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

0 голосов
/ 16 августа 2010

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

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

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

0 голосов
/ 16 августа 2010

Это зависит от используемых типов данных.

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

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

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

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

...