Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

null-terminated strings [D7]


Franzy ©   (2009-04-09 17:28:00) 

Тут при создании многоязыкового ПК всплыла проблема с сабжем. Надо дллке на фортране передать в качестве параметра строку. Проблема в том, что передается больше символов, чем нужно.

Я в дельфях создаю memory-mapped file, его имя передаю дллке, чтобы она его открыла и считала оттуда данные. Имя у меня объвлено как константа:
const  GeometryMap : PAnsiChar = 'PKSigma_Geometry_Map';

Когда я эту константу пытаюсь передать в длл, туда приходит строка 'PKSigma_Geometry_Map'+ еще под 200 символов всякого мусора. Догадываюсь, что проблема в том, что в фортране строки представляются иначе, чем в Дельфях и Винде. Вот, кстати, выдержка из СДК:
------------------------
Character Representation
A character string is a contiguous sequence of bytes in memory, as shown below.

A character string is specified by two attributes: the address A of the first byte of the string, and the length L of the string in bytes. The length L of a string is in the range 1 through 2,147,483,647 (2**31-1) .
------------------------------------------------------------
Если глянуть в tdump длл-ки, то видно, что строка-входной параметр представляется 8 байтами. Первые четыре, это, видимо, указатель на начало строки, а вторые четыре - длина строки. Т.е. теоретически я, наверно, могу составить эти 8 байт вручную (addr(GeometryMap),length(GeometryMap)) и передать их в дллку, но это как-то слишком по-хакерски.

Нет ли способа попроще? Может в дельфях есть строковый тип, в котором так же строки представляются?


Franzy   (2009-04-14 11:54:00) [1]

P.S. Кстати, заработало. Просто указываем еще один аргумент - длину строки, и все, никакого хакерства :)


Franzy   (2009-04-14 11:46:00) [2]

А во мне сильна тяга к экспериментаторству ;)


Игорь Шевченко   (2009-04-13 20:30:00) [3]

Franzy   (13.04.09 19:53) [10]

А зачем подозревать - проще почитать, поискать примеры межязыкового взаимодействия. Хоть бы и на С - они с Delphi одинаковы.
Мне лично читать лень :)


Franzy   (2009-04-13 19:53:00) [4]

Не совсем.... Есть подозрение, что можно вызывать так:

function FSReadGridData(const memorymap:PAnsiChar; const len: longint): longint; stdcall; external 'PKSSolver.dll' name '_FSREADGRIDDATA@8';

Завтра попробую, что получится.


Игорь Шевченко   (2009-04-13 18:38:00) [5]

Franzy   (13.04.09 18:11) [8]

http://www.ncsa.uiuc.edu/UserInfo/Resources/Software/Intel/Compilers/8.1/f_ug1/pgwchars.htm

оно ?


Franzy   (2009-04-13 18:11:00) [6]

Это моя функция, в СДК про нее ничего не написано :) Но если так интересно, то вот ее заголовок и кусок тела на фортране:

!  PKSSolver.f90
!*******************************************************************
function FSReadGridData(MapName)
!*******************************************************************
!  Эта функция считывает из указанного виртуального файла
!  (memory-mapped file) данные о сетке.
!
!  Функция должна возвращать код ошибки (0 = нет ошибки)
!*******************************************************************

!DEC$ ATTRIBUTES DLLEXPORT::FSReadGridData

USE sizeconstants
USE vars
USE DFWBASE, ONLY: CopyMemory
USE KERNEL32, ONLY: OpenFileMapping, MapViewOfFile, FILE_MAP_READ, UnmapViewOfFile  

 Implicit NONE
!---------------------------------
 Integer(4)                    :: FSReadGridData     ! Error code
 Character*(*)               :: MapName             ! Memmory-mapped file name
!---------------------------------
 
 Integer(SPOINTER)           :: GM_start, GM_caret ! Address pointers for memory reading
 Integer(SHANDLE)            :: GeometryMH         ! Handle for memory map
 
 Integer(4)                  :: i,j,k              ! Counters

!=============================
 
 ! Windows needs a null-terminated string as a paprameter, so add 0 char in the end

 GeometryMH = OpenFileMapping(FILE_MAP_READ,.FALSE.,MapName//CHAR(0))

 if (GeometryMH.EQ.0) then
   FSReadGridData =2001
   return
 end if

 GM_start = MapViewOfFile(GeometryMH,FILE_MAP_READ,0,0,0);

 GM_caret = GM_start;

................
................

 call UnmapViewOfFile(GM_start)

 FSReadGridData = 0

end function FSReadGridData


Игорь Шевченко   (2009-04-13 16:35:00) [7]

а объявление функции _FSREADGRIDDATA с параметрами посмотреть можно ? (Ну как оно в SDK написано, а не в твоей программе)


MBo   (2009-04-13 15:01:00) [8]

@8, если не ошибаюсь, означает, что функция ожидает 8 байтов параметров - возможно, еще длину туда передавать нужно.


Franzy   (2009-04-13 14:57:00) [9]

Сорри, что так долго не отвечал, были проблемы с инетом:

Передаю вот так:

В заголовке программы

function FSReadGridData(const memorymap:PAnsiChar): longint; stdcall; external 'PKSSolver.dll' name '_FSREADGRIDDATA@8';

а вызов так:

ec := FSReadGridData(GeometryMap);

Пробовал и напрямую строку передавать, не через константу, та же фигня.


Юрий Зотов   (2009-04-09 18:30:00) [10]

Например, что-то типа этого (проверьте правильност, набросал на скорую руку):

function DelToFor(const S: string): Int64;
begin
 Result := (integer(@S[1]) shl 32) or Length(S)
end;

function ForToDel(const F: Int64): string;
begin
  SetLength(Result, F and $FFFFFFFF);
  CopyMemory(Pointer(F shr 32), @Result[1], Length(Result))
end;


Игорь Шевченко   (2009-04-09 18:30:00) [11]

"Когда я эту константу пытаюсь передать в длл, туда приходит строка 'PKSigma_Geometry_Map'+ еще под 200 символов всякого мусора. Догадываюсь, что проблема в том, что в фортране строки представляются иначе, чем в Дельфях и Винде"

а как передаешь, можно посмотреть ?


Юрий Зотов   (2009-04-09 18:18:00) [12]

> (addr(GeometryMap)

addr(GeometryMap [1])

> Может в дельфях есть строковый тип, в котором так же строки
> представляются?

Готового нет. Но можно создать свой (record) или использовать Int64, а для преобразования написать простые функции.


Franzy   (2009-04-09 17:29:00) [13]

P.S. Собственно, null-terminated strings здесь при том, что винапишным функциям надо именно их передавать.


Наверх

Титульная страница Поиск, карта сайта Написать письмо