Модераторы: 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   Вверх
Ответ в темуСоздание новой темы Создание опроса
Прежде чем создать тему, посмотрите сюда:
mr.DUDA
THandle

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


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

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


 




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


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

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