Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2009.05.31;
Скачать: CL | DM;

Вниз

null-terminated strings   Найти похожие ветки 

 
Franzy   (2009-04-09 17:28) [0]

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

Я в дельфях создаю 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-09 17:29) [1]

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


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

> (addr(GeometryMap)

addr(GeometryMap[1])

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

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


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

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

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) [4]

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

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


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

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

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

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

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

а вызов так:

ec := FSReadGridData(GeometryMap);

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


 
MBo ©   (2009-04-13 15:01) [6]

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


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

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


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

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

!  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 18:38) [9]

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 19:53) [10]

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

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

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


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

Franzy   (13.04.09 19:53) [10]

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


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

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


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

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



Страницы: 1 вся ветка

Текущий архив: 2009.05.31;
Скачать: CL | DM;

Наверх




Память: 0.5 MB
Время: 0.009 c
2-1240003513
Gringoire
2009-04-18 01:25
2009.05.31
SQL запрос


15-1238275805
Юрий
2009-03-29 00:30
2009.05.31
С днем рождения ! 29 марта 2009 воскресенье


2-1239329769
trueTRIx
2009-04-10 06:16
2009.05.31
Как заменить курсор на свой


2-1239880524
mefodiy
2009-04-16 15:15
2009.05.31
"Белая форма"


15-1238103365
Юрий
2009-03-27 00:36
2009.05.31
С днем рождения ! 27 марта 2009 пятница