Как перенаправить объявление метода в C ++ / CLI, чтобы оно соответствовало сигнатуре метода Managed Extensions for C ++, который принимает ссылку на управляемый тип

Я хотел бы вызвать метод, компилируемый с /clr:oldsyntax (Управляемые расширения для синтаксиса C ++) из кода C ++, компилируемого с /clr (C ++ / CLI). Однако у меня возникли проблемы с прямым объявлением метода в C ++ / CLI, чтобы он соответствовал сигнатуре «Управляемые расширения для C ++».

Объявление в версии, использующей «Управляемые расширения для C ++», выглядит так:

void MangToUnMangDateTime(System::DateTime & managedDT, tm& unmangDT);

Примечание. Первый параметр (managedDT) является параметром, представляющим интерес для этого вопроса. В результате получается следующий msil для метода (найденный с помощью ildasm.exe):

.method assembly static void  MangToUnMangDateTime(valuetype [mscorlib]System.DateTime& modopt([mscorlib]System.Runtime.CompilerServices.IsImplicitlyDereferenced) managedDT,
                                                   valuetype tm* modopt([mscorlib]System.Runtime.CompilerServices.IsImplicitlyDereferenced) unmangDT) cil managed

Первая попытка:

Моя первая попытка пересылки объявления этого метода в C ++ / CLI выглядела так:

void MangToUnMangDateTime2(System::DateTime % managedDT, tm& unmangDT);

что привело к следующему msil:

.method assembly static void  MangToUnMangDateTime(valuetype [mscorlib]System.DateTime& managedDT,
                                                    valuetype tm* modopt([mscorlib]System.Runtime.CompilerServices.IsImplicitlyDereferenced) unmangDT) cil managed

который соответствует, за исключением дополнительного декларатора modopt MSIL, включенного в версию «Управляемые расширения для C ++»:

modopt([mscorlib]System.Runtime.CompilerServices.IsImplicitlyDereferenced) 

Вторая попытка

Моя вторая попытка пересылки объявления этого метода в C ++ / CLI выглядела так:

MangToUnMangDateTime(System::DateTime & managedDT, tm& unmangDT);

В качестве примечания: я был удивлен, что это скомпилировано на C ++ / CLI, так как я ожидал, что он захочет, чтобы я использовал синтаксис% для управляемого типа. Это привело к следующему msil:

.method assembly static void  MangToUnMangDateTime(valuetype [mscorlib]System.DateTime* modopt([mscorlib]System.Runtime.CompilerServices.IsImplicitlyDereferenced) managedDT,
                                                   valuetype tm* modopt([mscorlib]System.Runtime.CompilerServices.IsImplicitlyDereferenced) unmangDT) cil managed

Этот соответствует декларатору MSIL modopt, но является указателем * вместо ссылки &.

Вопрос:

Итак, есть ли у меня способ переслать объявление об этом в C ++ / CLI, чтобы оно соответствовало подписи в версии «Управляемые расширения для C ++»? Возможно, через атрибут в параметре?

Ограничения: я не хочу изменять версию «Управляемые расширения для C ++». Ясно, что если я изменю версию «Управляемые расширения для C ++», чтобы она передавалась по значению (что, вероятно, должно было быть в первую очередь):

void MangToUnMangDateTime(System::DateTime managedDT, tm& unmangDT);

тогда я могу получить сопоставление подписей, используя то же объявление в C ++ / CLI.


person Matt Smith    schedule 02.11.2010    source источник
comment
Остановите прямое объявление типов из другой сборки. Просто добавьте на него ссылку. Это больше не C, и файлы заголовков не нужны.   -  person Hans Passant    schedule 03.11.2010
comment
@Hans: Это не имеет никакого смысла - это не C #, это C ++ / CLI, поэтому файлы заголовков все еще существуют. Этот метод находится в той же сборке, просто в другом модуле компиляции. Заголовочный файл для одной единицы компиляции написан с использованием синтаксиса Managed Extensions for C ++ (/ clr: oldsyntax). Модуль компиляции, из которого я хочу вызвать метод, имеет синтаксис C ++ / CLI (/ clr). Таким образом, я не могу включить заголовок Managed Extensions, потому что компиляция в / clr не может понять синтаксис / clr: oldsyntax.   -  person Matt Smith    schedule 03.11.2010
comment
Им не обязательно участвовать в одном проекте. Сделайте 2 библиотеки DLL.   -  person Hans Passant    schedule 03.11.2010
comment
@Hans: Я подожду и посмотрю, получу ли я вместо этого ответ на свой вопрос. Спасибо.   -  person Matt Smith    schedule 03.11.2010


Ответы (2)


Возможно, я совершенно ошибаюсь, но разве мы не должны считать, что IL, созданный "Managed Extensions for C ++", в первую очередь сломан? Зачем вам добавлять атрибут IsImplicitlyDereferenced к параметру ссылки?

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

person icecrime    schedule 22.11.2010
comment
Полагаю, его можно было считать сломанным или устаревшим. Но я надеялся, что у меня есть хотя бы способ переслать объявление и вызвать его из той же сборки. Хотя, может, и нет. - person Matt Smith; 23.11.2010

Вероятно, вы захотите использовать ^ (_1 _) - это объявляет управляемую ссылку в C ++ / CLI. Я ничего не знаю о / oldsyntax, но он принимает ссылку на тип CLR, поэтому я думаю, что это эквивалент.

person Puppy    schedule 02.11.2010
comment
Ух, нет, DateTime - это тип значения. Символ ^ следует использовать только для ссылочных типов. - person Hans Passant; 03.11.2010
comment
Это не так. При этом создается следующий файл msil: .method assembly static void MangToUnMangDateTime (class [mscorlib] System.ValueType modopt ([mscorlib] System.DateTime) modopt ([mscorlib] System.Runtime.CompilerServices.IsBoxotype (mododoed) managed [mododo mscorlib] System.Runtime.CompilerServices.IsImplicitlyDereferenced) unmangDT) cil управляемый - person Matt Smith; 03.11.2010