Задача: вернуть 2 строки из вызова метода класса, написанного на MC++.
Вызывать его можно как MyClass.MyOp(ref s1, ref s2); или MyClass.MyOp(out s1, out s2); — правильно?
(начальные значения строк не важны в общем случае).
Как должны выглядеть definition/implementation этого метода в MC++ классе?
void MyClass::MyOp (System::String __gc * s1, System::String __gc * s2)
{
s1 = S"aaa"; s2 = S"bbb";
}
не работает — точнее, не распознается С# компилятором как метод с ref/out параметрами
Здравствуйте Newbie, Вы писали:
N>Привет всем,
N>Задача: вернуть 2 строки из вызова метода класса, написанного на MC++. N>Вызывать его можно как MyClass.MyOp(ref s1, ref s2); или MyClass.MyOp(out s1, out s2); — правильно? N>(начальные значения строк не важны в общем случае). N>Как должны выглядеть definition/implementation этого метода в MC++ классе? N>void MyClass::MyOp (System::String __gc * s1, System::String __gc * s2) N>{ N> s1 = S"aaa"; s2 = S"bbb"; N>} N>не работает — точнее, не распознается С# компилятором как метод с ref/out параметрами
И правильно делает, потому что String * — это аналог просто string в C#.
По идее, должно работать такое:
MyOp(String &s1,String &s2);
или такое:
MyOp((String *)&s1,(String *)&s2);
skip
L>И правильно делает, потому что String * — это аналог просто string в C#. L>По идее, должно работать такое: L>MyOp(String &s1,String &s2); L>или такое: L>MyOp((String *)&s1,(String *)&s2);
Что-то я сомневаюсь, что MC++ такое позволит, скорее уж:
Проверил:
L>>И правильно делает, потому что String * — это аналог просто string в C#. L>>По идее, должно работать такое: L>>MyOp(String &s1,String &s2);
Для C# это аналогично MyOp(string s1, string s2);
L>>или такое: L>>MyOp((String *)&s1,(String *)&s2);
А>Что-то я сомневаюсь, что MC++ такое позволит, скорее уж:
Позволяет, только скобки я там лишние поставил. Правильно будет:
MyOp(String * &s1, String * &s2). Для C# это будет MyOp(ref string s1, ref string s2).
Здравствуйте Андрей, Вы писали:
А>Здравствуйте Lexey, Вы писали:
L>>Как сделать out я так и не понял.
А>Например, так:
Гхм, насколько я понимаю, этот Out немного не из той оперы. Он имеет отношение только к COM InterOp'у. В C# — out, это аналог ref, но без начальной инициализации параметров. И значение параметра в функцию не передается.
Здравствуйте Lexey, Вы писали:
L>Гхм, насколько я понимаю, этот Out немного не из той оперы. Он имеет отношение только к COM InterOp'у. В C# — out, это аналог ref, но без начальной инициализации параметров. И значение параметра в функцию не передается.
Ничего подобного, он имеет отношение не только к InterOp'у — я проверял, и атрибут [Out] из MC++ маппируется в ключевое слово out языка C#.
Здравствуйте Андрей, Вы писали:
А>Здравствуйте Lexey, Вы писали:
L>>Гхм, насколько я понимаю, этот Out немного не из той оперы. Он имеет отношение только к COM InterOp'у. В C# — out, это аналог ref, но без начальной инициализации параметров. И значение параметра в функцию не передается.
А>Ничего подобного, он имеет отношение не только к InterOp'у — я проверял, и атрибут [Out] из MC++ маппируется в ключевое слово out языка C#.
Забавно, но как тогда объяснить вот такое:
Note that out is a keyword, and Out is an attribute. The example
class Class1
{
void M([Out] out int i) {
...
}
}
Мне кажется, что ты все-таки ошибаешься. Либо у писателей хелпов окончательно крыша съехала.
skip
L>Забавно, но как тогда объяснить вот такое:
L>
L>Note that out is a keyword, and Out is an attribute. The example
L>class Class1
L>{
L> void M([Out] out int i) {
L> ...
L> }
L>}
L>
L>Мне кажется, что ты все-таки ошибаешься. Либо у писателей хелпов окончательно крыша съехала.
Если ты посмотришь вопрос, который был задан, то увидишь, что речь шла о MC++. А как это в C# будет выглядеть — это уже дело десятое.
Да, в C# можно писать [Out] out и просто out — смысл один и тот же будет, только при чем здесь вопрос топика?
Здравствуйте Андрей, Вы писали:
А>Если ты посмотришь вопрос, который был задан, то увидишь, что речь шла о MC++. А как это в C# будет выглядеть — это уже дело десятое. А>Да, в C# можно писать [Out] out и просто out — смысл один и тот же будет, только при чем здесь вопрос топика?
Да в том-то вся и фишка, что в документации прямо утверждается, что [Out] и out в C# — это разные вещи. И про OutAttribute явно написано, что относится он только к InterOp'у.
Здравствуйте Lexey, Вы писали:
L>Здравствуйте Андрей, Вы писали:
А>>Если ты посмотришь вопрос, который был задан, то увидишь, что речь шла о MC++. А как это в C# будет выглядеть — это уже дело десятое. А>>Да, в C# можно писать [Out] out и просто out — смысл один и тот же будет, только при чем здесь вопрос топика?
L>Да в том-то вся и фишка, что в документации прямо утверждается, что [Out] и out в C# — это разные вещи. И про OutAttribute явно написано, что относится он только к InterOp'у.
Я думаю, эту дискуссию можно закрыть:
[Out] и out — 100% разные вещи:
1) out не требует привязки System.Runtime.InteropServices, а [Out] требует.
2) out требует обязательной инициализации параметра внутри функции, а [Out] — нет.
3) Если посмотреть в MSIL, то out и [Out] out порождают одинаковый прототип функции ([out] string &), а просто [Out] — другой ([out] string ), т.е. out подразумевает [Out], но не наоборот.
[Out] String ** или [Out] String * & действительно должны давать требуемый эффект out в C#.
Все это можно отлично увидеть на простом примере:
using System;
using System.Runtime.InteropServices;
namespace ClassLibrary1
{
/// <summary>
/// Summary description for Class1.
/// </summary>public class Class1
{
public Class1()
{
//
// TODO: Add constructor logic here
//
}
public void Test1(out string s)
{
s=null;
}
public void Test2([Out] string s)
{
//вот тут инициализация нафиг не нужна.
}
public void Test3([Out] out string s)
{
s=null;
}
}
}
Здравствуйте, Newbie, Вы писали:
N>Здравствуйте Lexey, Вы писали:
N>Спасибо за ответ!
L>Как сделать out я так и не понял.
N>Надо натравить атрибут [System::Runtime::InteropServices::Out] на описание параметров в определении метода:
N>void MyOp([System::Runtime::InteropServices::Out] System::String __gc ** s1);
N>и написать ее как:
N>void MyClass::MyOp(System::String __gc * * s1) N>{ N> *s1 = "ddd"; N>}
N>соответственно в IL она будет выглядеть так:
N>.method public instance void MyOp([out] string& s1) cil managed
N>PS: Вот ссылка на похожий вопрос с ответами чуваков из Visual C++ compiler team
а может кто-нибудь расскажет как все это прикрутить к массивам причем в упрощенной записи
например
Здравствуйте, Ed.ward, Вы писали:
EW>Здравствуйте, VladD2, Вы писали:
VD>>Здравствуйте, Ed.ward, Вы писали:
VD>>Видимо это баг 2002 стидии. Попробуй 2003-ью.
EW>Всмысле? EW>Какой баг? Я просто не представляю себе сигнатуру как это написать.
Я как-то делал не out, а ref-параетр в событии. Так студия упорно отказывалась признавать параметр за ref. Постоянно пыталась подставить знак "&". Естественно компилятор Шарпа орал как резаный. Причем я указывал и атрибуты и указатель двойной давал (в общем все делал по Ildasm-у). Но студия глючила по страшному. Потом сделал все тонкие места на Шарпе.
Может они это дело по фиксиили?...
... << RSDN@Home 1.0 beta 6a >>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.