Ada_Ru форум

Обсуждение языка Ада

Address, Access and C

Оставить новое сообщение

Сообщения

Vadim Godunko
Address, Access and C
2003-03-28 16:49:40

Добрый вечер!

 

Вот тут у меня вопрос на засыпку имеется.

 

Есть некоторый тип - запись, одно из полей которого - адрес. Так вот, иногда в это поле необходимо помещать адрес переменной. Тут проблем нет. А вот иногда в этом поле адрес переменной уже задан, и по нему необходимо занести значение.

 

Как красиво реализовать это на Ada?

hi,

Vadim Godunko wrote:

Добрый вечер!

>

Вот тут у меня вопрос на засыпку имеется.

>

Есть некоторый тип - запись, одно из полей которого - адрес. Так вот, иногда в это поле необходимо помещать адрес переменной. Тут проблем нет. А вот иногда в этом поле адрес переменной уже задан, и по нему

необходимо занести значение.

>

Как красиво реализовать это на Ada?

описать соответствующий ссылочный тип,

потом породить с помощью Unchecked_Convertion

функцию преобразования адреса в ссылочный тип:

Convertion_Function (Record_Variable.Address_Field).all := Some_Value;

так красиво?

Alex

hi,

Oleksandr Havva wrote:

hi,

>

Vadim Godunko wrote:

>

Добрый вечер!

>

Вот тут у меня вопрос на засыпку имеется.

>

Есть некоторый тип - запись, одно из полей которого - адрес. Так вот, иногда в это поле необходимо помещать адрес переменной. Тут проблем нет. А вот иногда в этом поле адрес переменной уже задан, и по нему

необходимо занести значение.

>

Как красиво реализовать это на Ada?

>

описать соответствующий ссылочный тип,

потом породить с помощью Unchecked_Convertion

млин...

я уже ваще сдурел :(

не Unchecked_Convertion, а System.Address_To_Access_Conversions

>

функцию преобразования адреса в ссылочный тип:

>

Convertion_Function (Record_Variable.Address_Field).all := Some_Value; >

так красиво?

>

Alex

Alex

Vadim Godunko wrote:

Есть некоторый тип - запись, одно из полей которого - адрес. Так вот, иногда в это поле необходимо помещать адрес переменной. Тут проблем нет. А вот иногда в этом поле адрес переменной уже задан, и по нему необходимо занести значение.

 

Как красиво реализовать это на Ada?

 

Красиво было бы избежать использовать адрес, а использовать сразу access type.

Допускаю что это иногда представляется невозможным.

Что мешает в данном случае использовать access type ?

Oleksandr Havva wrote:

 

Есть некоторый тип - запись, одно из полей которого - адрес. Так вот,

иногда в это поле необходимо помещать адрес переменной. Тут проблем нет.

А вот иногда в этом поле адрес переменной уже задан, и по нему

необходимо занести значение.

 

Как красиво реализовать это на Ada?

 

 

описать соответствующий ссылочный тип,

потом породить с помощью Unchecked_Convertion

функцию преобразования адреса в ссылочный тип:

 

Convertion_Function (Record_Variable.Address_Field).all := Some_Value;

 

так красиво?

 

Вполне, НО... необязательно Access имеет тот же размер, что и Address. И не обязательно это одно и тоже...

Dmitriy Anisimkov wrote:

 

Красиво было бы избежать использовать адрес, а использовать сразу access type.

Допускаю что это иногда представляется невозможным.

Что мешает в данном случае использовать access type ?

 

То, что эту чертову запись приходится добывать и глубин C-шной библиотеки (X Toolkit Intrinsics она называется). А содержимое поля может быть чем угодно - access type-ом не опишешь. :(

Oleksandr Havva wrote:

 

млин...

я уже ваще сдурел :(

не Unchecked_Convertion, а System.Address_To_Access_Conversions

 

На данный момент у меня так и сделано. Но может кто знает другие варианты?

Dmitriy Anisimkov wrote:

 

Красиво было бы избежать использовать адрес, а использовать сразу access

type.

Допускаю что это иногда представляется невозможным.

Что мешает в данном случае использовать access type ?

 

То, что эту чертову запись приходится добывать и глубин C-шной

библиотеки (X Toolkit Intrinsics она называется). А содержимое поля может быть чем угодно - access type-ом не опишешь. :(

 

Ada позволяет описывать С структуры. Есть прагма специальная, которая применяется к имени

record которая делает его совместимой с C структурой.

 

Вот цитата из Ада биндинга к ZLib.

 

type Z_Stream is record -- zlib.h:68

Next_In : Byte_Access; -- next input byte

Avail_In : UInt := 0; -- number of bytes available at next_in

Total_In : ULong := 0; -- total nb of input bytes read so far

Next_Out : Byte_Access; -- next output byte should be put there

Avail_Out : UInt := 0; -- remaining free space at next_out Total_Out : ULong := 0; -- total nb of bytes output so far msg : Chars_Ptr; -- last error message, NULL if no error

state : Voidp; -- not visible by applications zalloc : alloc_func := null; -- used to allocate the internal state

zfree : free_func := null; -- used to free the internal state opaque : Voidp; -- private data object passed to -- zalloc and zfree

data_type : Int; -- best guess about the data type: -- ascii or binary

adler : ULong; -- adler32 value of the uncompressed -- data

reserved : ULong; -- reserved for future use end record;

 

pragma Convention (C, Z_Stream);

--------------

 

Если в структуре есть поле в котором может быть указатель на "что-угодно." то можно либо использовать generic преобразование из access в address. (Это будет работать для C указателей и вроде бы это даже регламентировано RM.)

Либо еще можно надекларировать несколько рекордов, с разным access type внутри.

И прибиндить C функцию использующую разные рекорды несколько раз. Ето более типизированно, но если вариантов слишком много, будет слишком много деклараций.

Dmitriy Anisimkov wrote:

 

Если в структуре есть поле в котором может быть указатель на "что-угодно."

то можно либо использовать generic преобразование из access в address. (Это

будет работать для C указателей и вроде бы это даже регламентировано RM.)

 

Да, действительно, для C-совместимых типов, access будет эквивалентен address. Это определено (правда в общем виде для L-совместимых типов) в RM B.1.

 

Либо еще можно надекларировать несколько рекордов, с разным access type

внутри.

И прибиндить C функцию использующую разные рекорды несколько раз.

Ето более типизированно, но если вариантов слишком много, будет слишком

много деклараций.

 

 

Это действительно хороший вариант. Даже если много разных типов и подпрограмм, всё равно он дает лучшее понимание, что происходит.

 

У меня беда куда круче. Я пишу конвертор типов для файлов ресурсов - преобразование строкового образа в некоторое значение. Т.е. сама подпрограмма, хоть и писана на Ada, уже является C-совместимой и вызывается библиотекой при необходимости.

 

Переданные подпрограмме структуры содержат два поля: размер и адрес. Размер показывает сколько байт выделено в месте, куда указывает адрес. Так вот, если мне достаточно этой памяти, то я должен загнать туда значение, а в поле размера занести сколько моё значение реально занимает. А если не помещается - то самостоятельно выделить статический (в терминах C) сегмент и его адрес загнать в поле адреса, а размер - в поле размера.

Новое сообщение:
Страницы: 1

Чтобы оставить новое сообщение необходимо Зарегистрироваться и Войти