Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Начинающим";
Текущий архив: 2009.05.31;
Скачать: [xml.tar.bz2];

Вниз

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;
Скачать: [xml.tar.bz2];

Наверх





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


11-1201430310
=BuckLr=
2008-01-27 13:38
2009.05.31
Скорректировать описание RE_LineSpacing и RE_SpacingRule


2-1240027805
@!!ex
2009-04-18 08:10
2009.05.31
Как восстановить развертку TTreeView?


2-1239794145
Xoluay
2009-04-15 15:15
2009.05.31
Задание


2-1239793761
mnj
2009-04-15 15:09
2009.05.31
передача данных





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский