none
Visual Studio 2005 и большая проблема с Marshal.PtrToStructure(...) RRS feed

  • Вопрос

  • Долго пытался понять, что не так. А теперь ищу способ избавиться от этой проблемы.

    [return:MarshalAs(UnmanagedType.I4)]
    [
    DllImport("TestTkzDLL.dll")]
    public static extern int ExpFunc([In, Out]ref Test c);

    Структура для вызова процедурки
    StructLayout(LayoutKind.Sequential)]
    public struct Test
    {
    public Innerstr _in;
    [
    MarshalAs(UnmanagedType.ByValTStr,SizeConst=50)]
    public string str; // str[50];
    [MarshalAs(UnmanagedType.ByValArray,SizeConst=10)]
    public int[] IntArr; //IntArr[10];
    public IntPtr pInt; // int*
    public IntPtr pStruct; // innerstr*
    }

    Затем в коде я его генерирую указатель и значение в памяти
    int _pInt = 2010;
    IntPtr _pInt_buffer = Marshal.AllocCoTaskMem(Marshal.SizeOf(_pInt));
    Marshal.StructureToPtr(_pInt, _pInt_buffer, false);
    test.pInt = _pInt_buffer; // сохраняю указатель

    int
    retInt = ExpFunc(ref test);

    Console.WriteLine(" pInt = {0} [значение должно быть равно 5]", (int)Marshal.PtrToStructure(test.pInt, typeof(int)));

    В итоге получаю какое-то совершенно непонятное число. То же самое и с указателем pStruct (при попытке вызвать Marshal.PtrToStructure получаю неверные результаты)

    НО !!! Если запустить приложение вне Visual Studio, то получаю правильные результаты. Если очищу все ненужные файлы из проекта, то после запуска в Visual Studio (неважно Release или Debug), то значения снова правильные ... но только на один запуск. Потом почему-то снова всё неправильно отображает.

    У нас установлен Visual Studio 2005 Professional, система Windows XP SP2

     

    • Перемещено Siddharth Chavan 1 октября 2010 г. 22:09 MSDN Forums Consolidation (От:Visual C#)
    10 декабря 2009 г. 14:49

Ответы

  • Я в шоке. Случайно наткнулся на то, как это само собой решилось. Решение крайне простое и совершенно не понятно, как это может быть взаимосвязано )))

    Достаточно хотя бы один раз вызвать Console.WriteLine(); // можно даже текст вписать для приличия )))
    И всё, после этого все данные преобразовываются верно :)

    PS: тему можно закрывать. Если кто знает как консоль решает проблему с Marshal.PtrToStructure буду рад выслушать
    • Помечено в качестве ответа Sergey Grigorev 11 декабря 2009 г. 7:13
    11 декабря 2009 г. 7:13

Все ответы

  • Практически наугад, неизвестно что у тебя в ExpFunc происходит, но попробуй http://msdn.microsoft.com/en-us/library/ms185330.aspx
    10 декабря 2009 г. 18:18
  • Содержание функции ExpFunc

        char str[250]="";
        *(s->in.in_pInt) = 1;
        s->in.Int = 5;
        s->pInt = &(s->in.Int);
        s->in.str[5] = 0;
        s->IntArr[0] = 10;
        s->in.in_pInt = s->IntArr;
        strcpy(s->str, "ПРЕВЕД!");
        s->pStruct = &(s->in);
        return 1;

    Код не мой, коллега по работе написал. Моя задача проверить, как работается с указателями IntPtr.
    Заметил также, что при попытке получить данные из IntPtr pStruct; вот так:
                
    Innerstr t1 = (Innerstr)Marshal.PtrToStructure(test.pStruct, typeof(Innerstr));
    Console.WriteLine("pStruct.str = {0}", t1.str);

    Получаю, что вместо текста Hello там лежит 0, Culture=neutral, PublicKeyToken=b77a5c561934e089 (это только если запускать из под Visual Studio)
    11 декабря 2009 г. 6:12
  • Практически наугад, неизвестно что у тебя в ExpFunc происходит, но попробуй http://msdn.microsoft.com/en-us/library/ms185330.aspx

    К сожалению, несмотря на то, что полученные данные изменились после этого, всё равно из под отладчика получаю неверные результаты
    11 декабря 2009 г. 6:29
  • Я в шоке. Случайно наткнулся на то, как это само собой решилось. Решение крайне простое и совершенно не понятно, как это может быть взаимосвязано )))

    Достаточно хотя бы один раз вызвать Console.WriteLine(); // можно даже текст вписать для приличия )))
    И всё, после этого все данные преобразовываются верно :)

    PS: тему можно закрывать. Если кто знает как консоль решает проблему с Marshal.PtrToStructure буду рад выслушать
    • Помечено в качестве ответа Sergey Grigorev 11 декабря 2009 г. 7:13
    11 декабря 2009 г. 7:13
  • Скорее всего случайность вроде выделения памяти по другому. Наверняка будет падать время от времени.

    А вообще говоря надо было по меньшей мере привести определение структур в C. Скорее всего определение в C# попросту неверное.
    This posting is provided "AS IS" with no warranties, and confers no rights.
    11 декабря 2009 г. 20:08
    Модератор