Форум: "Начинающим";
Текущий архив: 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