MC++ & ref/out
От: Newbie  
Дата: 02.04.02 06:21
Оценка:
Привет всем,

Задача: вернуть 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 параметрами

Спасибо!
MCP.NET
Re: MC++ & ref/out
От: Lexey Россия  
Дата: 02.04.02 08:15
Оценка:
Здравствуйте 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);
Re[2]: MC++ & ref/out
От: Андрей Россия  
Дата: 02.04.02 09:49
Оценка:
Здравствуйте Lexey, Вы писали:

skip

L>И правильно делает, потому что String * — это аналог просто string в C#.

L>По идее, должно работать такое:
L>MyOp(String &s1,String &s2);
L>или такое:
L>MyOp((String *)&s1,(String *)&s2);

Что-то я сомневаюсь, что MC++ такое позволит, скорее уж:

void MyClass::MyOp(String** s1, String** s2)
{
  *s1 = S"aaa";
  *s2 = S"bbb";
}
Re[3]: MC++ & ref/out
От: Lexey Россия  
Дата: 02.04.02 12:06
Оценка: 2 (1)
Здравствуйте Андрей, Вы писали:

Проверил:

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).


А>
А>void MyClass::MyOp(String** s1, String** s2)
А>{
А>  *s1 = S"aaa";
А>  *s2 = S"bbb";
А>}
А>


Это тоже проходит и тоже аналогично MyOp(ref string s1, ref string s2).

Как сделать out я так и не понял.
Re[4]: MC++ & ref/out
От: Андрей Россия  
Дата: 02.04.02 12:37
Оценка:
Здравствуйте Lexey, Вы писали:

L>Как сделать out я так и не понял.


Например, так:

  [
  ComImport,
  Guid("0002E011-0000-0000-C000-000000000046"),
  InterfaceType(ComInterfaceType::InterfaceIsIUnknown)
  ]
  public __gc __interface IEnumCATEGORYINFO 
  {
    [PreserveSig]
    int Next([In] UInt32 celt,
             [Out, MarshalAs(UnmanagedType::LPArray, SizeParamIndex=0)]
             CATEGORYINFO rgelt __gc[],
             [Out] UInt32* pceltFetched);

    [PreserveSig]
    int Skip([In] UInt32 celt);

    [PreserveSig]
    int Reset();

    [PreserveSig]
    int Clone([Out, MarshalAs(UnmanagedType::Interface)] IEnumCATEGORYINFO** ppenum);
  };
Re[5]: MC++ & ref/out
От: Lexey Россия  
Дата: 02.04.02 13:34
Оценка:
Здравствуйте Андрей, Вы писали:

А>Здравствуйте Lexey, Вы писали:


L>>Как сделать out я так и не понял.


А>Например, так:


Гхм, насколько я понимаю, этот Out немного не из той оперы. Он имеет отношение только к COM InterOp'у. В C# — out, это аналог ref, но без начальной инициализации параметров. И значение параметра в функцию не передается.
Re[4]: MC++ & ref/out
От: Newbie  
Дата: 02.04.02 16:48
Оценка: 14 (2)
Здравствуйте Lexey, Вы писали:

Спасибо за ответ!

L>Как сделать out я так и не понял.


Надо натравить атрибут [System::Runtime::InteropServices::Out] на описание параметров в определении метода:

void MyOp([System::Runtime::InteropServices::Out] System::String __gc ** s1);

и написать ее как:

void MyClass::MyOp(System::String __gc * * s1)
{
*s1 = "ddd";
}

соответственно в IL она будет выглядеть так:

.method public instance void MyOp([out] string& s1) cil managed

PS: Вот ссылка на похожий вопрос с ответами чуваков из Visual C++ compiler team
MCP.NET
Re[6]: MC++ & ref/out
От: Андрей Россия  
Дата: 03.04.02 01:57
Оценка:
Здравствуйте Lexey, Вы писали:

L>Гхм, насколько я понимаю, этот Out немного не из той оперы. Он имеет отношение только к COM InterOp'у. В C# — out, это аналог ref, но без начальной инициализации параметров. И значение параметра в функцию не передается.


Ничего подобного, он имеет отношение не только к InterOp'у — я проверял, и атрибут [Out] из MC++ маппируется в ключевое слово out языка C#.
Re[7]: MC++ & ref/out
От: Lexey Россия  
Дата: 03.04.02 06:45
Оценка:
Здравствуйте Андрей, Вы писали:

А>Здравствуйте 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) {
      ...
   }
}


Мне кажется, что ты все-таки ошибаешься. Либо у писателей хелпов окончательно крыша съехала.
Re[8]: MC++ & ref/out
От: Андрей Россия  
Дата: 03.04.02 06:59
Оценка:
Здравствуйте Lexey, Вы писали:

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 — смысл один и тот же будет, только при чем здесь вопрос топика?
Re[9]: MC++ & ref/out
От: Lexey Россия  
Дата: 03.04.02 07:12
Оценка:
Здравствуйте Андрей, Вы писали:

А>Если ты посмотришь вопрос, который был задан, то увидишь, что речь шла о MC++. А как это в C# будет выглядеть — это уже дело десятое.

А>Да, в C# можно писать [Out] out и просто out — смысл один и тот же будет, только при чем здесь вопрос топика?

Да в том-то вся и фишка, что в документации прямо утверждается, что [Out] и out в C# — это разные вещи. И про OutAttribute явно написано, что относится он только к InterOp'у.
Re[10]: MC++ & ref/out
От: Lexey Россия  
Дата: 03.04.02 07:32
Оценка:
Здравствуйте 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;
        }
    }
}
Re[11]: MC++ & ref/out
От: Андрей Россия  
Дата: 03.04.02 07:34
Оценка:
Здравствуйте Lexey, Вы писали:

skip

Наконец-то!!!
Re[12]: MC++ & ref/out
От: Lexey Россия  
Дата: 03.04.02 07:48
Оценка:
Здравствуйте Андрей, Вы писали:

А>Наконец-то!!!


Вздохнул с облегчением? Может тебя еще помучать?
Re[5]: MC++ & ref/out & Arrays
От: Ed.ward Россия  
Дата: 06.05.03 01:31
Оценка:
Здравствуйте, 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



а может кто-нибудь расскажет как все это прикрутить к массивам причем в упрощенной записи
например

C#
static void Main( )
{
  //...
  Byte[] buffer;
  mcppObj.Test( out buffer );
}



MС++
void Test( [System::Runtime::InteropServices::Out] /*вот что надо здесь написать?*/ buffer )
{
  buffer = Array::CreateInstance( Type::GetType( S"Byte" ), 10 );
}
Re[6]: MC++ & ref/out & Arrays
От: VladD2 Российская Империя www.nemerle.org
Дата: 06.05.03 22:10
Оценка:
Здравствуйте, Ed.ward, Вы писали:

Видимо это баг 2002 стидии. Попробуй 2003-ью.
... << RSDN@Home 1.0 beta 6a >>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[7]: MC++ & ref/out & Arrays
От: Ed.ward Россия  
Дата: 07.05.03 01:36
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Здравствуйте, Ed.ward, Вы писали:


VD>Видимо это баг 2002 стидии. Попробуй 2003-ью.


Всмысле?
Какой баг? Я просто не представляю себе сигнатуру как это написать.
А может так и вовсе нельзя?
потому что вот так все Ok


//C#
static void Main()
{
  //...
  System.Array buffer;
  mcppObj.Test( out buffer );
}




//MC++
using namespace System::Runtime::InteropServices;

void MCPPObj::Test( [Out] System::Array **buffer )
{
  *Buffer = Array::CreateInstance( Type::GetType( S"Byte" ), 10 );
}
Re[8]: MC++ & ref/out & Arrays
От: VladD2 Российская Империя www.nemerle.org
Дата: 07.05.03 21:03
Оценка:
Здравствуйте, Ed.ward, Вы писали:

EW>Здравствуйте, VladD2, Вы писали:


VD>>Здравствуйте, Ed.ward, Вы писали:


VD>>Видимо это баг 2002 стидии. Попробуй 2003-ью.


EW>Всмысле?

EW>Какой баг? Я просто не представляю себе сигнатуру как это написать.

Я как-то делал не out, а ref-параетр в событии. Так студия упорно отказывалась признавать параметр за ref. Постоянно пыталась подставить знак "&". Естественно компилятор Шарпа орал как резаный. Причем я указывал и атрибуты и указатель двойной давал (в общем все делал по Ildasm-у). Но студия глючила по страшному. Потом сделал все тонкие места на Шарпе.

Может они это дело по фиксиили?...
... << RSDN@Home 1.0 beta 6a >>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.