Модераторы: Partizan, gambit
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Маршалинг структуры в C#. Генерится исключение! 
:(
    Опции темы
bitwise
Дата 21.4.2008, 08:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 6
Регистрация: 21.4.2008

Репутация: нет
Всего: нет



Всем привет!

Я пишу обертку на C# для С-библиотечки. Так вот, у меня есть структуры:
Код

struct params
{
    char*   info;
    params* next;
};

struct device
{
    unsigned int flags;
    char*        name;
    char*        description;
    params*      p_params;
    device*      next;
};



И есть пара функций:
Код

int get_device_list( device* dev );
void free_device_list( device* dev );


Так вот, что делаю я:
Код


[StructLayout(LayoutKind.Sequential)]
public class device
{
   [MarshalAs(UnmanagedType(UnmanagedType.U4)
   uint flags;

   [MarshalAs(UnmanagedType(UnmanagedType.LPStr)
   string name;

   [MarshalAs(UnmanagedType(UnmanagedType.LPStr)
   string description;

   IntPtr p_params;
   IntPtr next;

   public device() 
   {
      name        = new string( '\0', 100 );
      description = new string( '\0', 100 );
      flsgs       = 0;
      p_params    = IntPtr.Zero;
      next        = IntPtr.Zero;
   }

}

// Экспортирую ф-ции из DLL
   [Dllimport("api.dll")]
   static extern int get_device_list( IntPtr device_ptr );

   [Dllimport("api.dll")]
   static extern int free_device_list( IntPtr device_ptr );


public static void main()
{
    device dev;
    IntPtr device_ptr = Marshal.AllocHGlobal( Sizeof( typeof( device ) ) );
    Marshal.StructureToPtr( dev, device_ptr, false ) );

    int result = get_device_list( device_ptr ); // Здесь все хорошо
    
    free_device_list( device_ptr ); // А здесь бросается исключение "Попытка чтения или записи в защищенную память. Возможно память повреждена"

    Marshal.FreeHGlobal( device_ptr );
}




Так вот я не понимаю, почему отрабатывает вызов первой функции и не отрабатывает вызов второй. Помогите пожалуйста, че-то я никак не соображу где ошибся. Спасибо.

PM MAIL   Вверх
mullih
Дата 21.4.2008, 10:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 75
Регистрация: 19.12.2006

Репутация: нет
Всего: 2



Может
void free_device_list( device* dev );
   [Dllimport("api.dll")]
   static extern int free_device_list( IntPtr device_ptr );

Это сообщение отредактировал(а) mullih - 21.4.2008, 10:30
PM MAIL WWW Skype   Вверх
bitwise
Дата 21.4.2008, 10:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 6
Регистрация: 21.4.2008

Репутация: нет
Всего: нет



Прошу прщения, я очепятался...

int get_device_list( device* dev );
void free_device_list( device* dev );

и соответственно...

[Dllimport("api.dll")]
static extern int get_device_list( IntPtr device_ptr );

[Dllimport("api.dll")]
static extern void free_device_list( IntPtr device_ptr );
PM MAIL   Вверх
mullih
Дата 21.4.2008, 10:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 75
Регистрация: 19.12.2006

Репутация: нет
Всего: 2



а можно код функций
int get_device_list( device* dev );
void free_device_list( device* dev );
PM MAIL WWW Skype   Вверх
bitwise
Дата 21.4.2008, 11:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 6
Регистрация: 21.4.2008

Репутация: нет
Всего: нет



К сожалению кода нет... Это сторонняя DLL smile 
Может я структуру неправильно отмаршалил?


Это сообщение отредактировал(а) bitwise - 21.4.2008, 11:06
PM MAIL   Вверх
mullih
Дата 21.4.2008, 11:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 75
Регистрация: 19.12.2006

Репутация: нет
Всего: 2



С описанием не помогу так как точно не уверен но попробуй в шарпе 
struct params
{
    char*   info;
    params* next;
};

описать и p_params сделать объетом этой структуры

PM MAIL WWW Skype   Вверх
bitwise
Дата 21.4.2008, 14:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 6
Регистрация: 21.4.2008

Репутация: нет
Всего: нет



Я обязательно попробую и отпишусь о результате...
PM MAIL   Вверх
mr.DUDA
Дата 24.4.2008, 10:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


3D-маньяк
****


Профиль
Группа: Экс. модератор
Сообщений: 8244
Регистрация: 27.7.2003
Где: город-герой Минск

Репутация: 110
Всего: 232



Цитата(bitwise @  21.4.2008,  11:04 Найти цитируемый пост)
Может я структуру неправильно отмаршалил?

Вместо IntPtr можно саму структуру по ref передать:
Код
   [Dllimport("api.dll")]
   static extern int get_device_list(ref device device_ptr);

   [Dllimport("api.dll")]
   static extern void free_device_list(ref device device_ptr);


public static void main()
{
    device dev = new device();

    int result = get_device_list(ref dev);
    
    free_device_list(ref dev);
}




--------------------
user posted image
PM MAIL WWW   Вверх
bitwise
Дата 24.4.2008, 10:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 6
Регистрация: 21.4.2008

Репутация: нет
Всего: нет



В общем бага оказалась надуманной, всем спасибо за брейнсторм.

Оказывается ф-ция выглядит так: int get_device_list( device** dev ); вместо int get_device_list( device* dev ); Поэтому все и падало....

Я вот еще что не понимаю.
Есть некая функция в some.dll, которая принимает указатель на структурку:
 
Код

struct my_data
{  
     unsigned int data;
};

void init_my_data( my_data* pdata)
{
       pdata->data = 256;
}


Так вот что делаю я :
Код


[StructLayout(LayoutKind.Sequential)]
public class MyData
{
        [MarshalAs(UnmanagedType.U4)]
        public UInt32 number = 0;
}

[DllImport("some.dll")]
public static void init_my_data( IntPtr pdata );

public static int  main()
{
    IntPtr pdata = IntPtr,Zero;
    pdata = Marshal.AllocHGlobal(Marshal.Sizeof(typeof(MyData)));  // здесь pdata получает определенное значение.

    init_my_data(pdata); // Вызов отрабатывает хорошо. НО! После вызова меняется значение pdata!!!

    Marshal.FreeHGlobal(pdata); // Здесь облом, потому что pdata переписан!!!
}


При передаче параметра в функцию как IntPtr он переписывается. Насколько я понимаю так не должно быть и для того чтобы освободить память я сохраняю первоначальное значение в old_pdata, чтобы потом по нему освободить память. Но это коряво.
Подскажите что я неправильно делаю???
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Прежде чем создать тему, посмотрите сюда:
mr.DUDA
THandle

Используйте теги [code=csharp][/code] для подсветки кода. Используйтe чекбокс "транслит" если у Вас нет русских шрифтов.
Что делать если Вам помогли, но отблагодарить помощника плюсом в репутацию Вы не можете(не хватает сообщений)? Пишите сюда, или отправляйте репорт. Поставим :)
Так же не забывайте отмечать свой вопрос решенным, если он таковым является :)


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, mr.DUDA, THandle.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Общие вопросы по .NET и C# | Следующая тема »


 




[ Время генерации скрипта: 0.0456 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.