[Delphi 2006] Ошибка доступа в память при передаче данных в длл
Какое выравнивание структур стоит в dll'ке и в программе на паскале?
AIsearcher.getItems возвращает указатель, полученный от сишной dll'ки?Да, абсолютно верно.
Какое выравнивание структур стоит в dll'ке и в программе на паскале?
TintSearch = class
public
procedure SetMinStemLen(len:integer); virtual; stdcall; abstract;
procedure SetBadSymbols(bs: pchar); virtual; stdcall; abstract;
procedure SetDictPath(dp: pchar); virtual; stdcall; abstract;
procedure SetLenWordsValues(list, listK: pchar); virtual; stdcall; abstract;
procedure SetDictValues(dictlistK: pchar); virtual; stdcall; abstract;
procedure searchString(s: pchar); virtual; stdcall; abstract;
function getCount: integer; virtual; stdcall; abstract;
function getItems: isearch; virtual; stdcall; abstract;
function stemka(str: pchar): pchar; virtual; stdcall; abstract;
procedure filter(border:integer); virtual; stdcall; abstract;
end;
TInitSearch = function : PintSearch; stdcall;
TDelSearch = procedure (ex : PintSearch); stdcall;
IntSearchPointer:=InitSearch;
AIsearcher:=pointer(IntSearchPointer);
AIsearcher.SetMinStemLen(strtoint(OkofAISearchForm.MinStemLen.text;
AIsearcher.SetBadSymbols(pchar(OkofAISearchForm.BadSymbols.Text;
бла-бла-бла.
Сишное описание (только описание, доступа к полному коду у меня нет)
class intSearch{
public:
intSearch(void);
~intSearch(void);
virtual void __stdcall SetMinStemLen(long len);
virtual void __stdcall SetBadSymbols(char *bs);
virtual void __stdcall SetDictPath(char *dp);
virtual void __stdcall SetLenWordsValues(char *list, char *listK);
virtual void __stdcall SetDictValues(char *dictlistK);
virtual void __stdcall searchString(char *s);
virtual long __stdcall getCount(void);
virtual isearch * __stdcall getItems(void);
virtual char * __stdcall stemka(char *str);
};
typedef intSearch *(__stdcall *pFunc3void);
typedef void (__stdcall *pFunc4intSearch *ex);
Выравнивание стоит и там и там по единичке.
(Record field alingment =1)
Вообше меня интересует правомерность строчки
ItemsElements:=pointer(ItemsPointer);
Откуда он знает сколько записей копировать?
Я конечно поставил перед нимвыделение памяти, но оно и без этого компилилось.
1. Ты используешь C++ класс из дельфи. Классы в C++ и дельфи не совместимы!
2. Ты считаешь, что указатели (на массивы) в C++ соотвествуют динамическим массивам в дельфи. Динамические массивы в дельфи имеют более сложную стуктуру.
Если это действительно так, то меня удивляет как твоя программа не падает на много раньше сложения строк.
пишется небольшая dll'ка на такой же версии компилятора С++ (иначе бинарной совместимости классов может не быть которая преобразует ООП-интерфейс в процедурный интерфейс. Затем эта библиотека используется в Delphi. При необходимости, можно сделать обратное преобразование процедурного интерфейса в ООП.
А если тебя интересует какого хрена между классами в с++ и delphi нет совместимости - познакомься с технологией COM, которая ровно для этого и предназначена.
1. Ты используешь C++ класс из дельфи. Классы в C++ и дельфи не совместимы!Результаты однако прога выдаёт верные...
Насчёт дллки - она на си потому что её пишут на стороне(1С) и мы покупаем её для использования в нашей проге.
пишется небольшая dll'ка, которая преобразует ООП-интерфейс в процедурный интерфейс. При необходимости, можно сделать обратное преобразование процедурного интерфейса в ООП.Ну, во первых это требует бОльших процессорных мощностей (преобразование туда-сюда а уже и так всё прилично подтормаживает(0.5-1сек на позицию во вторых, всё равно в итоге процедурный интерфейс в конечном счёте выдаст тот же самый динамический массив.
type
tarray=array [1..1000000] of dictout;
parray=^tarray;
но ни в коем случае как array of dictout.
Переходники - это пара call'ов, а потому замедлят работу незначительно.
Результаты однако прога выдаёт верные...Ну тогда и сегфолтов в твоей проге тоже нет, это так - наваждение.
Шварцнегер тоже может вставить квадратный брусок в круглое отверстие, но это не повод следовать его примеру, если у тебя нет столько силы.
virtual isearch * __stdcall getItems(void);
>>>>>>>>
Tisearcharray = array of Tisearch;
isearch = ^Tisearcharray;
и
dictout *items;
>>>>>>
items: array of Tdictout;
Хотя с первого взгляда не зная си не поймёшь(а я в нём ни бум-бум).
попробую сейчас так:
TdictoutArray = array of Tdictout;
Pdictout = ^TdictoutArray;
............
items: Pdictout;
SetLength(tmpArray,ItemsElements[j].NumberOfElements);
tmpArray:=pointer(ItemsElements[j].items);
for k := 0 to ItemsElements[j].NumberOfElements-1 do
begin
name:=(tmpArray[k].name);
delete(name,pos(' ',namelength(name;
outputstring:=outputstring+' WORD: '+name+' val: '+inttostr(tmpArray[k].value)+
' dicVal: '+inttostr(tmpArray[k].dic_value)+' addVal: '+inttostr(tmpArray[k].add_value);
end;
tmpArray:=nil;
Всё равно падает =(
FreeLibrary(LibHandle);
LibHandle := LoadLibrary(fullpath);
array of something и array [1..100000] of something - это 2 большие разницы. Первое всегда занимает 4 байта, поскольку является указателем на что-то типа vector в C++.
Кажись разобрались. Я как-то не обратил сразу внимания на то, что он стал вылетать с другим эксэпшеном. Теперь он обсчитывает ГОРАЗДО больше строчек прежде чем упасть. И падает уже с аксесс виолэйшн дллке на передаче ей очередной строки.
Насчёт дллки - она на сиси и С++ - это разные языки
ты уж определись какнить
учитывая что есть классы, то скорее это С++
Оставить комментарий
kill-still
Собственно кросспост с кингдома:http://www.delphikingdom.com/asp/answer.asp?IDAnswer=60806
День добрый уважаемые жители королевства.
Второй день бьюсь над багом и не могу понять, что происходит.
Есть класс, который получен из длл, в него передаются нек-е значения. код такой:
Спустя какое-то время (если за раз много элементов кинуть (firstrow << lastrow или много раз по чуть-чуть) оа падает с ошибкой доступа в память. Такое впечатление, что при сложении строк она "наезжает" на недоступный кусок памяти.
Такой же пример на си работает без сбоев, т.е. дело не в длл.
Суть кода в том, чтобы из ItemsElements полученных из длл перенестиданные в нужный нам формат в OkofAISearchArray. Утечек памяти нет (проверял FastMM). Что происходит - понять не могу падает на простом сложении строчек.
Сишное описание выходного массива: