Вызов С# из С++, 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
}