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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> C++ <-> C# 
:(
    Опции темы
zss
Дата 30.11.2006, 20:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



есть простая структура на C++
Код
struct S
{
    int a;
    int b;
    char str [32];
}


я передаю ее через сокет и получаю массив byte[].
мне приходится создавать промежеточную структуру
Код
unsafe public struct S1
{
    public int a;
    public int b;
    public fixed byte str[32];
}


преобразовывать массив байт к ней
Код
static public T ToStruct<T>(byte[] buffer)
{
    IntPtr ptr = Marshal.AllocHGlobal(buffer.Length);
    Marshal.Copy(buffer, 0, ptr, buffer.Length);
    T obj = (T)Marshal.PtrToStructure(ptr, typeof(T));
    Marshal.FreeHGlobal(ptr);
    return obj;
}


а потом руками заполнять поля S2
Код
unsafe public static string ToString(byte* buffer, int size)
{
    int index = 0;
    byte[] data = new byte [size];
    for (; index < size; ++index)
    {
        if (buffer[index] == 0) break;
        data[index] = buffer[index];
    }
    return Encoding.GetEncoding(1251).GetString(data, 0, index);
}

public struct S2
{
    public int a;
    public int b;
    public string str;

    public S (S1 obj)
    {
        a = obj.a;
        b = obj.b;
        str = ToString (obj.str, 32);
    }
}


тоже и в обратную сторону.

Есть ли способ сразу получить из S -> S2 и из S2 -> S ?
PM MAIL ICQ   Вверх
mr.DUDA
Дата 30.11.2006, 23:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


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


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

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



Можно, если заюзать не unsafe а обычную структуру с атрибутом [StructLayout(LayoutKind.Explicit)] и над массивом поставить  [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]


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


Опытный
**


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

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



Цитата(mr.DUDA @  30.11.2006,  23:49 Найти цитируемый пост)
Можно, если заюзать не unsafe а обычную структуру с атрибутом [StructLayout(LayoutKind.Explicit)] и над массивом поставить  [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)] 


mr.DUDA, а можно примерчик - я пока не силен в C#
PM MAIL ICQ   Вверх
mr.DUDA
Дата 1.12.2006, 12:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


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


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

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



Вот код, с кое-какими поправками от первого совета smile

SomeDll.cpp
Код
#include "stdafx.h"

BOOL APIENTRY DllMain(HMODULE hModule, DWORD  ul_reason_for_call, LPVOID lpReserved)
{
    return TRUE;
}


struct TheStructure
{
    int a;
    int b;
    char str[32];
};

extern "C" void  __declspec(dllexport) FillMyStruct(TheStructure *ret)
{
    ret->a = 1;
    ret->b = 2;
    strncpy(ret->str, "Very simple ASCII string", 32);
}



Program.cs
Код
using System;
using System.Text;
using System.Runtime.InteropServices;

[StructLayout(LayoutKind.Sequential)]
struct TheManagedStructure
{
    public int a;
    public int b;
    [MarshalAs(UnmanagedType.ByValArray, SizeConst=32)]
    public byte[] buf;
}

class Program
{
    [DllImport("SomeDll.dll")]
    extern static void FillMyStruct(ref TheManagedStructure s);

    static void Main()
    {
        TheManagedStructure s = new TheManagedStructure();
        FillMyStruct(ref s);

        Console.WriteLine(Encoding.ASCII.GetString(s.buf));
    }
}



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


Опытный
**


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

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



а сразу в string нельзя ? только в byte[]
PM MAIL ICQ   Вверх
zss
Дата 1.12.2006, 19:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



кстати есть еще типичная несовместимость типов

например bool в C++ 1 байт, а в C# 4 байта. Можно ли это тоже уровнять ?
PM MAIL ICQ   Вверх
Naum
Дата 2.12.2006, 11:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 743
Регистрация: 7.9.2005
Где: Саратов, ул. Поса дского, 298

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



Цитата(zss @  1.12.2006,  20:59 Найти цитируемый пост)
например bool в C++ 1 байт, а в C# 4 байта.
 С чего ты взял? bool в C# тоже 1 байт. 100%.

Добавлено @ 11:26 
Да и вообще, если увидишь в каком-либо  языке программирования, что экземпляр типа true\false, больше 1 байта, можешь сразу бросать этот язык. Думаю, ты понимаешь, почему.


--------------------
У нас всего два праздника Новый год и ТЯПница.
PM MAIL ICQ   Вверх
ivashkanet
Дата 2.12.2006, 11:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Кодю потиху
****


Профиль
Группа: Участник Клуба
Сообщений: 3684
Регистрация: 23.2.2006
Где: Гомель, Беларусь

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



Цитата(Naum @  2.12.2006,  10:23 Найти цитируемый пост)
bool в C# тоже 1 байт

It is true.
Но храниться в стеке как 4 байта (последние 3 пустые)

Добавлено @ 11:37 
Цитата(Naum @  2.12.2006,  10:23 Найти цитируемый пост)
Да и вообще, если увидишь в каком-либо  языке программирования, что экземпляр типа true\false, больше 1 байта, можешь сразу бросать этот язык. Думаю, ты понимаешь, почему. 

Naum, бросай C#  smile 
PM MAIL WWW ICQ   Вверх
Naum
Дата 2.12.2006, 11:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 743
Регистрация: 7.9.2005
Где: Саратов, ул. Поса дского, 298

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



Цитата(ivashkanet @  2.12.2006,  12:36 Найти цитируемый пост)
Но храниться в стеке как 4 байта (последние 3 пустые)

Упс.  smile 
Цитата(ivashkanet @  2.12.2006,  12:36 Найти цитируемый пост)
Naum, бросай C#    

Так я еще толком и не начинал.  smile



--------------------
У нас всего два праздника Новый год и ТЯПница.
PM MAIL ICQ   Вверх
zss
Дата 2.12.2006, 12:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Цитата(Naum @  2.12.2006,  11:59 Найти цитируемый пост)
Упс. 

вот и я об этом. долго ловил косяк, пока не проверил размер smile
PM MAIL ICQ   Вверх
mr.DUDA
Дата 2.12.2006, 14:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


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


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

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



Размер bool-поля структуры можно задать тем же самым [MarshalAs(UnmanagedType.I1)]. Также можно поюзать [StructLayout(LayoutKind.Explicit)] в паре с [FieldOffset(смещение_в_байтах)] над полями.


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


Опытный
**


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

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



mr.DUDA, а что за I1?

и спасибо за помощь во всех моих темах smile.

З.Ы. У меня складывается впечатление, что ты знаещь какую-то волшебную книгу по C# раз столько знаний.
Поделись названием smile

Добавлено @ 23:11 
З.Ы.Ы. кстати все эти MarshalAs сохраняются только на следующую строку или можно на все структуру сразу задать ?
PM MAIL ICQ   Вверх
mr.DUDA
Дата 3.12.2006, 00:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


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


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

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



zss, технология и язык достаточно простые, чтобы освоить за полгода. Всё упирается в опыт использования конкретных вещей.

Цитата(zss @  2.12.2006,  22:08 Найти цитируемый пост)
кстати все эти MarshalAs сохраняются только на следующую строку или можно на все структуру сразу задать ?

На каждое поле в отдельности.


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


Опытный
**


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

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



странно, то после этих изменений перестал выполняться код

я сделал так
Код

    [StructLayout(LayoutKind.Sequential)]
    public struct PointHeader
    {
        public ulong time;
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 6)]
        public byte[] buffer;
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 32 + 1)]
        public string name;
        public uint count;
    };



теперь слетает при попытке определить размер
int size = Marshal.SizeOf(obj);

и говорит, что
Код

An unhandled exception of type 'System.ArgumentException' occurred in mcl.dll

Additional information: Type 'PointHeader' cannot be marshaled as an unmanaged structure; no meaningful size or offset can be computed.


З.Ы. Кстати маршалинг также не работает если это не структура, а класс. Почему ?
PM MAIL ICQ   Вверх
mr.DUDA
Дата 3.12.2006, 11:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


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


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

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



Строку нельзя маршаллизировать как массив. Для строк есть отдельный тип маршаллизации: ByValTStr. К тому же, не мешало бы указать что структура выровнена по границам 1 байта, а для строк используется charset ANSI (1 байт на символ):

Код
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)]
public struct PointHeader
{
    public ulong time; // 8 байт
    [MarshalAs(UnmanagedType.ByValArray, SizeConst = 6)]
    public byte[] buffer; // 6 байт
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32 + 1)]
    public string name; // 33 байта
    public uint count; // 4 байта
} // в сумме = 51 байт


Цитата(zss @  3.12.2006,  10:14 Найти цитируемый пост)
З.Ы. Кстати маршалинг также не работает если это не структура, а класс. Почему ?

Работает.


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


Опытный
**


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

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



Цитата(mr.DUDA @  3.12.2006,  11:56 Найти цитируемый пост)
Строку нельзя маршаллизировать как массив. Для строк есть отдельный тип маршаллизации: ByValTStr. К тому же, не мешало бы указать что структура выровнена по границам 1 байта, а для строк используется charset ANSI (1 байт на символ):

блин... если библиотека под Compact FW, то многое недоступно.
Например CharSet.Ansi и Pack.

Что же все так сложно-то. Почему такая несовместимость ?

Добавлено @ 13:09 
Хотя в MSDN говориться что это доступнов CF2.0

но компилятор говорит
Код

'System.Runtime.InteropServices.CharSet' does not contain a definition for 'Ansi'
'System.Runtime.InteropServices.StructLayoutAttribute' does not contain a definition for 'Pack'


Это сообщение отредактировал(а) zss - 3.12.2006, 13:16
PM MAIL ICQ   Вверх
zss
Дата 3.12.2006, 13:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Цитата(mr.DUDA @  3.12.2006,  11:56 Найти цитируемый пост)
Работает. 

да вот не совсем

у меня вываливает с исключением
Код

Type 'MyClass' cannot be marshaled as an unmanager structure; no meaningful size or offset can be computed;

PM MAIL ICQ   Вверх
mr.DUDA
Дата 3.12.2006, 16:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


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


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

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



Цитата(zss @  3.12.2006,  12:56 Найти цитируемый пост)
у меня вываливает с исключением Type 'MyClass' cannot be marshaled as an unmanager structure; no meaningful size or offset can be computed;

Покажи что за класс.

З.Ы. про Compact Framework лучше не спрашивать  smile 


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


Опытный
**


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

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



Цитата(mr.DUDA @  3.12.2006,  16:42 Найти цитируемый пост)
про Compact Framework лучше не спрашивать

так это очень интерисует smile


Цитата(mr.DUDA @  3.12.2006,  16:42 Найти цитируемый пост)
Покажи что за класс.

переделал класс на структуру - все заработало... странно
PM MAIL ICQ   Вверх
zss
Дата 3.12.2006, 19:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



возникла еще проблемма - неправильно работает
Marshal.PtrToStructure

до массива все нормально, а при первом byte[] все сбивается
Что ему опять не так ?
PM MAIL ICQ   Вверх
zss
Дата 3.12.2006, 19:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



с этим вроде разобрался (моя ошибка smile) - всем спасибо
жаль только в CF не работает CharSet и Pack и не получилось маршалить классы smile

Если не сложно - есть еще вопросики к специалистам маршалинга

1. Сокер работает с массивами byte[]. Приходится преобразовывать структуру к массиву, читать в него, а
потом обратно гнать в структуру. Это не очень удобно. Можно ли как сказать, что структура
есть массив байт. А сколько ее размер - пусть считает (или на крайний случай самому говорить размер)

2. Можно ли как читать не всю структуру, а например только ее первые N полей

PM MAIL ICQ   Вверх
mr.DUDA
Дата 3.12.2006, 22:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


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


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

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



1 - нет
2 - нет

Побори свою лень  smile 


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


Опытный
**


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

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



Цитата(mr.DUDA @  3.12.2006,  22:02 Найти цитируемый пост)
Побори свою лень  

ладно - поборол smile но классы маршалить напрочь отказывается - как быть ?
PM MAIL ICQ   Вверх
mr.DUDA
Дата 6.12.2006, 21:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


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


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

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



Чтоб маршалило классы - надо либо поставить [Serializable], либо наследовать от MarshalByRefObject


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


Опытный
**


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

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



Цитата(mr.DUDA @  6.12.2006,  21:56 Найти цитируемый пост)
Чтоб маршалило классы - надо либо поставить [Serializable], либо наследовать от MarshalByRefObject 

а что дас первый случай и что второй ?
PM MAIL ICQ   Вверх
mr.DUDA
Дата 6.12.2006, 22:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


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


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

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



Взято из вопросов по ремоутингу: первое даст возможность передававать объект из одного аппдомена в другой по значению, а второе - по ссылке (с прокси). Ты говоришь о маршаллинге - мой ответ как раз о маршаллинге. Заметь, не о сериализации или записи объекта в стрим; а именно о передаче из одного контекста в другой (из одного аппдомена в другой, из одного процесса в другой).


--------------------
user posted image
PM MAIL WWW   Вверх
Страницы: (2) [Все] 1 2 
Ответ в темуСоздание новой темы Создание опроса
Прежде чем создать тему, посмотрите сюда:
mr.DUDA
THandle

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


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

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


 




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


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

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