Вызов С# из С++, Reverse P/Invoke, DLL смешанного режима и С++/CLI

Как я понимаю, я могу использовать обратный P/Invoke для вызова С# из С++. Обратный P/Invoke - это просто случай:

  • Создайте свой управляемый класс (С#).
  • Создайте проект библиотеки классов С++/cli (ранее управляемый С++). Используйте это, чтобы вызвать управляемый класс С# (предположительно через ссылку).
  • Вызвать код С++/cli из native С++.

Вопросы:

  • Правильно ли это?
  • Является ли DLL, созданная на шаге 2, известной как DLL смешанного режима?
  • Имеет ли С++/CLI полностью замененный управляемый С++ в отношении MS?
  • Можно ли полностью избежать COM, используя этот подход?
  • В какой момент будет создаваться и запускаться CLR и кем?

Заранее спасибо

Ответы

Ответ 1

Вот ответы, насколько мне известно:

  • Да
  • Да, это DLL с смешанным режимом (на самом деле вы можете создать один файл вашего собственного проекта на С++ и создать этот класс С++/CLI в этом файле и вызвать код непосредственно из этого файла. для выполнения этого требуется отдельная DLL.
  • С++/CLI и Managed С++ представляют одну и ту же вещь. Единственное различие заключается в том, что в старой версии до Visual Studio 2003 она называлась Managed С++. Позднее синтаксис был изменен довольно много, и он был переименован в С++/CLI. Подробнее см. эту ссылку.
  • Да
  • CLR будет использоваться всякий раз, когда выполняется вызов управляемой DLL.

Ответ 2

Обратите внимание, что вы также можете совершить обход IL файла DLL С# и экспортировать статические методы, которые работают в основном так же, как и экспорт в С++/CLI. Тем не менее, это всегда шаг после компиляции, и он имеет некоторые оговорки (которые также имеют экспорт С++/CLI, кстати.).

Вы можете ILDASM как с С#, так и с С++/CLI DLL, чтобы увидеть, как экспорт дон; это что-то вроде этого (от образец в сети):

// unmexports.il
// Compile with : ilasm unmexports.il /dll
assembly extern mscorlib {}
..assembly UnmExports {}
..module UnmExports.dll
// This flag is important
..corflags 0x00000002
// This instructs the CLR to create a marshaling thunk for the unmanaged caller
..vtfixup [1] int32 fromunmanaged at VT_01
..data VT_01 = int32(0)
..method public static void foo()
{
..vtentry 1:1
..export [1] as foo
ldstr "Hello from managed world"
call void [mscorlib]System.Console::WriteLine(string)
ret
}

Ответ 3

С ilasm 2.0 вам нужно меньше кода, потому что он может генерировать большую часть мусора отдельно. Теперь действительно нужна директива .export.

// unmexports.il
// Compile with : ilasm unmexports.il /dll
.assembly extern mscorlib { auto }
.assembly UnmExports {}
.module UnmExports.dll
.method public static void foo()
{
  .export [1] as foo
  ldstr "Hello from managed world"
  call void [mscorlib]System.Console::WriteLine(string)
  ret
}