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

Вниз

Вызов функции из DLL. Мистика   Найти похожие ветки 

 
pasha_golub ©   (2012-02-17 14:11) [0]

Друзья, конечно же мистики быть не может, но мой мозг устал. Взываю к ноосфере.

Имеем:

PGconn *PQconnectdbParams(const char **keywords, const char **values, int expand_dbname);


Обявляем у себя:
type  TPQconnectdbParams = function(Keywords: PPAnsiChar; Values: PPAnsichar; ExpandDBName: integer): PPGconn; cdecl;

var TPQconnectdbParams: TPQconnectdbParams


Используем:

function _PQConnectDBParams(AParams: TStrings; ExpandDbName: boolean = False): PPGConn;
var
 ConnKeywords, ConnValues: packed array of PAnsiChar;
 K,V: AnsiString;
 i: integer;
begin
 SetLength(ConnKeywords, AParams.Count);
 SetLength(ConnValues, AParams.Count);
 for i := 0 to AParams.Count - 1 do
  begin
    K := UTF8Encode(AParams.Names[i]); //since this is connection assume we"ll use UTF8
    GetMem(ConnKeywords[i], Length(K) + 1);
    StrPCopy(ConnKeywords[i], K);
    V := UTF8Encode(AParams.ValueFromIndex[i]);
    GetMem(ConnValues[i], Length(V) + 1);
    StrPCopy(ConnValues[i], V);
  end;
  try
    Result := PQconnectdbParams(@ConnKeywords[0], @ConnValues[0], ord(ExpandDbName));
  finally
    for i := 0 to AParams.Count - 1 do
     begin
      FreeMem(ConnValues[i]);
      FreeMem(ConnKeywords[i]);
     end;
  end;
end;


Но беда. Иногда, при чем фиг пойми при каких условиях, первый вызов не работает. То есть возвращается nil, а повторный работает. На некоторых машинах в ответ выдается такая ошибка, что существует подозрение на неверно сконструированные параметры.

Я знаю, как это переписать и есть рабочий код. Но тысяча чертей! Что тут не так?


 
icWasya ©   (2012-02-17 14:16) [1]

Не знаю что это за DLL, но, навскидку, а как она определяет размер массива Keywords и Values? Может быть в конце надо добавить нулевой элемент?


 
jack128_   (2012-02-17 14:20) [2]

сколько символов копирует StrPCopy ?? Length(Str) или Length(Str) + 1 ??  Если первое, то у тя нет гарантии, что строки нулем заканчиваются..


 
pasha_golub ©   (2012-02-17 14:20) [3]


> Может быть в конце надо добавить нулевой элемент?

Логично, чтоб мне на Бейсике всю жизнь программировать! Щас попробую


 
pasha_golub ©   (2012-02-17 14:21) [4]


> сколько символов копирует StrPCopy

Копирует Length(str) и завершает нулем.


 
pasha_golub ©   (2012-02-17 14:32) [5]


> icWasya ©   (17.02.12 14:16) [1]

Василий, ты гений! С меня пивас! И того получилось:
function _PQConnectDBParams(AParams: TStrings; ExpandDbName: boolean = False): PPGConn;
var
 ConnKeywords, ConnValues: packed array of PAnsiChar;
 K,V: AnsiString;
 i: integer;
begin
 SetLength(ConnKeywords, AParams.Count + 1);
 SetLength(ConnValues, AParams.Count + 1);
 for i := 0 to AParams.Count - 1 do
  begin
    K := UTF8Encode(AParams.Names[i]); //since this is connection assume we"ll use UTF8
    GetMem(ConnKeywords[i], Length(K) + 1);
    StrPCopy(ConnKeywords[i], K);
    {$IFDEF DELPHI_7}
    V := UTF8Encode(AParams.ValueFromIndex[i]);
    GetMem(ConnValues[i], Length(V) + 1);
    StrPCopy(ConnValues[i], V);
  end;
  try
    ConnKeywords[High(ConnKeywords)] := nil; //icWasya is a God!
    ConnValues[High(ConnValues)] := nil; //icWasya is a God!
    Result := PQconnectdbParams(@ConnKeywords[0], @ConnValues[0], ord(ExpandDbName));
  finally
    for i := 0 to AParams.Count - 1 do
     begin
      FreeMem(ConnValues[i]);
      FreeMem(ConnKeywords[i]);
     end;
  end;
end;



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

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

Наверх




Память: 0.48 MB
Время: 0.006 c
15-1402829721
Юрий Зотов
2014-06-15 14:55
2015.01.18
Диск накрылся - чем лечить?


2-1387504983
Drowsy
2013-12-20 06:03
2015.01.18
Будет ли время вычислений меньше.


15-1402753733
Override Func
2014-06-14 17:48
2015.01.18
Пересечение прямоугольника и окружности


15-1402175199
Андрюша
2014-06-08 01:06
2015.01.18
Как избежать Deadlock в Firebird?


15-1402311626
KilkennyCat
2014-06-09 15:00
2015.01.18
Delphi + Asterisk