Форум: "Основная";
Текущий архив: 2003.05.12;
Скачать: [xml.tar.bz2];
ВнизПроблема с DLL Найти похожие ветки
← →
Петр (2003-04-25 05:53) [0]Уважаемые знатоки! Помогите Please...
Есть такая проблема: Имею модуль GOST, в котором описаны следующие функции:
Function Coder(Key,tString : String): String;
Function DeCoder(Key,tCryptString : String) : String;
Создаю DLL
{Исходный код}
library GostLib;
Uses
SysUtils,Classes,GOST;
Exports
Coder,
DeCoder;
begin
End.
DLL создается, но при попытке вызова этой DLL из другой программы, постоянно возникает ошибка Invalid Pointer Operation, хотя если использовать функции этого модуля не через DLL, то все работает как часы.
Ниже приведу код вызова DLL из другой программы:
Type
Function Coder(Key,tString : String) : String; stdcall;
Function DeCoder(Key,tCryptString : String) : String; stdcall;
var
Form1: TForm1;
implementation
Function Coder; external "GostLib.dll";
Function DeCoder; external "GostLib.dll";
procedure TForm1.Button1Click(Sender: TObject);
Var
Key : String;
S,ST : String;
begin
Key:="ddddddddiiiiiiiiiidddddddddddDELPHI DLL";
S:=Coder(Key,Edit1.Text);
Edit2.Text:=S;
S:=DeCoder(Key,S);
Edit3.Text:=S;
end;
Заранее благодарю,
с уважением, Петр.
← →
MBo (2003-04-25 06:37) [1]uses sharemem!!!!!!
← →
Palladin (2003-04-25 06:54) [2]лучьше бы ты к генерированому автоматически с уважнием относился...
и читал иногда, что пишут то...
← →
Петр (2003-04-25 07:42) [3]Если честно, то я не понял о чем идет речь...можно подробнее?
← →
MBo (2003-04-25 07:44) [4]создай новую DLL и прочитай автоматический комментарий
← →
evvcom (2003-04-25 08:06) [5]Воткни первым юнитом в uses sharemem и проверь также, чтобы в dll функции Coder и Decoder также имели директивы stdcall (или убери их в вызывающем exe). А то как-то поразному они описаны в вопросе.
← →
VAleksey (2003-04-25 08:52) [6]Совет простой. Читать надо больше.
← →
Петр (2003-04-25 09:07) [7]Я понимаю, что я тормоз полный: Сделал так, как описано в литературе, а результат нулевой.
Как Sharemem Использовать? Есть ли у Вас примеры?
← →
MBo (2003-04-25 09:10) [8]Все его использование заключается в написании его первым в списке uses и программы и библиотеки.
Кроме того, соглашения о вызове ОБЯЗАНЫ быть одинаковыми (например, stdcall)
← →
Петр (2003-04-25 09:18) [9]Попробовал вставить Sharemem в библиотеку и в модуль с функциями - все равно такая же ошибка.
← →
evvcom (2003-04-25 09:22) [10]Ну а про stdcall понял или нет? Или просто игнорируешь? Дождешься, все просто забьют на дальнейшие твои вопросы и делов-то!
← →
Palladin (2003-04-25 09:23) [11]
> Петр © (25.04.03 09:07)
а еще нужно быть увереным что все передается правильно
и в 17 строке ошибки нет
← →
Петр (2003-04-25 09:35) [12]> evvcom
Я же использую Stdcall как в модуле GOST, где хранятся функции, определяю в области Var
Function Coder(Key,tString : String): String; stdcall;
Function DeCoder(Key,tCryptString : String) : String; stdcall;
, а в области Implementation эти же функции у меня без stdcall.
Я не могу понять, что я неправильно делаю?
> Palladin
Что касается передачи параметров, то здесь я все проверил:
Если рассмотреть процедуру обработки нажатия кнопки, то исключительная ситуация возникает на строке Edit3.Text:=S;
Если эту строку убрать, то исключительая ситуация возникает на предшествующей строке S:=DeCoder(Key,S);
Как это понять? , хотя результат, который выдают функции Coder и DeCoder в деббагере выдается корректным.
procedure TForm1.Button1Click(Sender: TObject);
Var
Key : String;
S,ST : String;
begin
Key:="ddddddddiiiiiiiiiidddddddddddDELPHI DLL";
S:=Coder(Key,Edit1.Text);
Edit2.Text:=S;
S:=DeCoder(Key,S);
Edit3.Text:=S;
← →
evvcom (2003-04-25 09:47) [13]> Петр
Просто не надо зацикливаться на одном и игнорировать другое. stdcall (или другие соглашения) должны присутствовать или не присутствовать одинаково в interface секции как dll, так и exe-модуля! От этого зависит как будут передаваться параметры (через стек или регистры), и кто будет чистить потом стек (вызывающая или вызываемая сторона). В секции implementation повторно использовать данные директивы необязательно.
← →
Palladin (2003-04-25 09:47) [14]
> Петр © (25.04.03 09:35)
если
uses sharemem именно так как сказал borland и MBo © (25.04.03 09:10)
то ошибка в 17 строке dll
скорее всего ты там выходишь за рамки строки
← →
Петр (2003-04-25 10:08) [15]> evvcom
Так у меня stdcall прсутствует, как в вызываемом модуле, так и в модуле DLL.
Я уже вынес функции Coder и DeCoder в DLL и добавил соглашения stdcall в DLL., Однако та же ситуация. Может я идиот?
← →
evvcom (2003-04-25 10:11) [16]Приведи полный текст. Боюсь к "текст" добавить слово "значимый".
← →
Петр (2003-04-25 10:21) [17]> evvcom
Кинь мыло? Все тексты примерно около 40K
← →
evvcom (2003-04-25 10:38) [18]Тогда все же попробуй добавить слово "значимый", а ковыряться в чужих 40 кБ - что-то ломово.
← →
Петр (2003-04-25 10:51) [19]> evvcom
Что имеется в виду?
"Тогда все же попробуй добавить слово "значимый"
← →
evvcom (2003-04-25 11:16) [20]А выше читать не пробовал? evvcom © (25.04.03 10:11)
"Значимый" в данном случае - это значит текст кода, в котором скрывается (или может скрываться) твоя проблема. То бишь зачем приводить текст вычисления вероятности попадания Незнайки на луну, если это никак не влияет ни на вызов dll, ни на использование sharemem сразу после слова uses.
← →
Петр (2003-04-25 12:12) [21]> evvcom
Привожу исходный текст моего примера:
1 DLL
library GostLib;
Uses
ShareMem,SysUtils,Classes,GOST;
Exports
Coder,
DeCoder;
// GammaCoder,
// GammaDeCoder;
begin
end.
2. Модуль GOST
unit GOST;
interface
Uses
ShareMem,Math;
Type
Const
Var
Function Coder(Key,tString : String; Var tCryptString : String): Integer; stdcall;
Function DeCoder(Key,tCryptString : String; Var tString : String) : Integer; stdcall;
implementation
Function Coder(Key,tString : String): String;
Var
i,j,Temp,StringSize,
StringNewSize : Integer;
b : Byte;
Remainder : Byte; //
← →
evvcom (2003-04-25 12:31) [22]Ну а в unit Unit1; где ShareMem? Хотя особо с шареной памятью не пробовал работать, но на это здесь уже не раз указывалось.
← →
Петр (2003-04-25 12:55) [23]Спасибо Вам за помощь !!!!
Попробовал дописать Sharemem в Unit1,действительно, ошибка исчезла, но появилось новое проявление: При закрытии программы (формы) возникает ошибка Runtime Error 217.
И говориться, что это неизвестное программное исключение.
← →
Ru (2003-04-25 13:09) [24]Возможно я дико ошибаюсь, но в описании юнита GOST отсутствует объявление функций (или оно несоответствует), а ошибка, в таком случае, возникает из-за того, что ехе не может найти требуемую функцию. Это если я не ошибаюсь.
← →
Петр (2003-04-25 13:18) [25]Из внешней программы (Модуля Unit1) Вызывается 2 функции: Coder и DeCoder.
В модуле GOST Они есть, я их привел. Хотя модуль GOST содержить более 20 других Функций, я их не страл здесь приводить, из-за большого объема.
Меня сейчас интересует другое: почему при закрытии программы, которая вызывает DLL, возникает ошибка?
← →
Fredericco (2003-04-25 13:34) [26]ShareMem, не выход.
1) Передаваемые данные как в ДЛЛ так и из ДЛЛ - PChar.
2) При возврате результата из ДЛЛ в ЕХЕ ее вызвавшую нужно самому жестко резервировать память под возвращаемую строку. Приблизительный код в ДЛЛ:
var
hGlobalMemory: THandle;
..................
function YouFunc(....):PChar;
var
ResultStr:string;
begin
............
Result:=AlcMemory(ResultStr);
end;
................
function AlcMemory(Str: PChar): PChar ;
var
lpGlobalMemory: pointer ;
begin
lpGlobalMemory:=nil;
hGlobalMemory:=GlobalReAlloc(hGlobalMemory,StrLen(Str)+1, GMEM_MOVEABLE);
if hGlobalMemory<>0 then begin
IpGlobalMemory:=GlobalLock(hGlobalMemory);
lstrcpy(lpGlobalMemory,Str);
GlobalUnlock(hGlobalMemory);
end;
Result:=PChar(lpGlobalMemory);
end;
.........
initialization
hGlobalMemory := GlobalAlloc(GMEM_MOVEABLE , 1);
← →
Fredericco (2003-04-25 13:36) [27]Не забудь убрать ShareMem из ДЛЛ и ЕХЕ !
← →
EK (2003-04-25 13:50) [28]Hello peterka,
Я силно не вникал, и нверняка пишу глупость, но пусть будет.
1)Насчет DLL. У меня точно такая же проблема была.
Только не помню, как ее решил. Там какая-то глупая ошибка:
Что-то на уровне:
Было так:
Function Coder; external "GostLib.dll";
Function DeCoder; external "GostLib.dll";
Попробуй как-то так:
Function Coder; external "GostLib.dll";stdcall;
Function DeCoder; external "GostLib.dll";stdcall;
2)Если код функций невелик, то ты уверен, что тебе вообще надо делать
dll?
--
E.K.
mailto:vgekata@mail.ru
← →
EK (2003-04-25 13:53) [29]pardon, я тут почитал форум - stdcall уже замусолили насмерть...
← →
evvcom (2003-04-25 13:59) [30]F7 и F8 тоже очень часто помогают решить проблему.
← →
icWasya (2003-04-25 14:42) [31]если использовать ShareMem, то его надо ставить ПЕРВЫМ в списке Uses во всех проектах - и в DLL и в EXE
← →
jack128 (2003-04-25 15:27) [32]Читаю я Вас и слезами горючими обливаюсь ;-))
Пример
Код в DLL
library Project2;
uses
ShareMem,
SysUtils,
Classes;
{$R *.RES}
function MyStrFunc: string;stdcall;
begin
Result := "My String";
end;
exports
MyStrFunc;
begin
end.
Код в программе
в файле проэкта
program Project1;
uses
ShareMem,
Forms,
Unit1 in "Unit1.pas" {Form1};
....
в файле Unit1
function MyStrFunc: string;stdcall; external "project2.dll" name "MyStrFunc";
procedure TForm1.Button1Click(Sender: TObject);
begin
Caption := MyStrFunc;
end;
← →
Петр (2003-04-28 07:40) [33]Попробовал последний вариант с ShareMem - Работает!
Спасибо Вам большое. Но есть дополнительный вопрос.
Из другого проекта Delphi DLL грузится без проблем. Что нужно сделать, чтобы моя DLL грузилась не из Delphi, а в FoxPro
Попробовал Fox"e. загрузить, говорит, что ошибка загрузки 32 битной DLL.
Влияет ли на данную ситуацию то, что DLL была сгенерирована в Win2000, а Fox стоит на машине, где Win98?
← →
MBo (2003-04-28 07:50) [34]при использовании DLL с другими языками нельзя использовать типы, присущие только Delphi, а именно - String (тем более, что дли таких строк еще и менеджер памяти дельфийский должен работать). Используй PCHar
← →
Петр (2003-04-28 09:01) [35]> MBo
Так ведь String универсальный тип данных (В фоксе тоже есть String, а PChar"a там нет). И как же тогда быть?
← →
VAleksey (2003-04-28 09:03) [36]Тушите свет.
← →
MBo (2003-04-28 09:10) [37]>Петр
название, конечно, похожее, но организация разная.
Тебе бы книжек почитать, да хелп.
← →
Петр (2003-04-28 09:24) [38]Смеяться конечно можно, однако, если сталкиваешься с какой-то проблемой впервые...
Сильный и умный не тот, кто осмеивает, а тот, кто способен понять и помочь...в противном случае - осмеять, значит проявить слабость...
Не смотря на это, я благодарен всем, кто внес свою лепту и оказал поддержку.
С уважением, Петр.
← →
Digitman (2003-04-28 09:55) [39]
> Петр
> Так ведь String универсальный тип данных (В фоксе тоже есть
> String, а PChar"a там нет).
С чего ты взял, что "String универсальный тип" ?
String в Object Pascal - действительно, удобный тип хранения/обработки ANSI-строковых данных в некоем унифицированном формате.
Но !!
Мало ли что подразумевается под String в FoxPro !
Мало ли что подразумевается под String в VisualBasic !
Да мало ли. в конце концов, в Бразилии "Педро" !
А вот для унифицированной передачи строковых параметров между модулями многие языковые среды имеют спец.префиксные конструкции, указывающие на то, что стр.данные передаются в вызываемому коду в виде адреса первого байта в цепочке стр.символов (а-ля ByRef в VisualBasic). Этот адрес без проблем м.б. получен вызываемой ObjectPascal-проц-рой/ф-цией, если параметр объявлен как PChar.
← →
Петр (2003-04-28 10:44) [40]А если использовать Variant?
← →
evvcom (2003-04-28 10:45) [41]А Variant и вовсе никто кроме дельфи не поймет.
← →
Digitman (2003-04-28 10:57) [42]
> Петр
почитай в док-ции по FoxPro, каков там синтаксис вызова внешних процедур для явной передачи параметров по ссылке, и передавай стр.параметры именно по ссылке, а не по значению.
← →
Петр (2003-04-28 11:12) [43]Размышляя над данной проблемой пришел к таким выводам:
Если дело в String"ах, то должно ли это означать, что DLL совсем нельзя загрузить в Fox"е? Может ли проблема быть в некорректной компиляции DLL? (или параметры компоновки), может быть существуют параметры компилятора, влияющие на использование DLL, созданных в Delphi, в других средах.
К вопросу о использовании PChar:
Входными параметрами к моим функциям на данный момент является String. Программист, который пишет на Fox"e передаст в нее переменную, в которой строка. Не вызовет ли это исключительную ситуацию в моей программе? Каким образом воспримет моя функция такую передачу, т.е. какой тип данных она определит для себя?
← →
Digitman (2003-04-28 11:24) [44]
> Если дело в String"ах, то должно ли это означать, что DLL
> совсем нельзя загрузить в Fox"е?
Нет, не должно. Отказ от String (и в Fox и в Делфи) в пользу простых указательных типов решает проблему.
> Может ли проблема быть в некорректной компиляции DLL? (или
> параметры компоновки),
Нет здесь проблем никаких. Проблема одна - в понимании того, как и что передается от вызывающего к вызываемому коду, и в межязыковых соглашениях о вызовах.
> К вопросу о использовании PChar:
иные варианты, как правило, приведут к непредсказуемым последствиям.
добейся соглашения с Fox-программистом о том, чтобы он передавал тебе стр.параметры по ссылке
тогда, объявив их у себя как PChar (при stdcall-соглашении о вызове) ты легко решишь проблему
← →
Петр (2003-04-28 11:56) [45]> Digitman
Я поговорил с Fox-программистом, он не совсем понял, что означает передача строковых параметров по ссылке (в данном контексте).
К сожалению, я совсем не знаю Fox"a ,но попробую объяснить:
Допустим, он у себя объявит массив
Dim C[15], т.е. массив С из 15 символов, и передаст этот массив на вход моей процедуры, а у меня будет входной параметр tString : PChar;
Получится, что строка, которая содержится в массиве С[15] без проблем запишется в tStirng?
← →
Digitman (2003-04-28 12:18) [46]
> Я поговорил с Fox-программистом, он не совсем понял, что
> означает передача строковых параметров по ссылке
Fox-программист вообще в состоянии документацию к своему инструменту читать ? Ну ведь есть же мануал, в котором описывается синтаксис объявления параметров внешних ф-ций ! Там же, наверняка, есть что-то похожее на ByRef/ByVal. И, скорей всего, какие-то комментарии есть по каждой такой конструкции.
В любом случае, тебе нужно задать вопрос о соглашениях Fox (при вызове внешних ф-ций) не здесь, а фоксовикам в "Базы данных"
> Dim C[15],
а разве это - строковая переменная ?? это же - переменная типа массив !!
> Получится, что строка, которая содержится в массиве С[15]
> без проблем запишется в tStirng: PChar ?
Глубоко сомневаюсь в этом.
← →
evvcom (2003-04-28 14:07) [47]> Digitman © (28.04.03 12:18)
> Петр ©
Может и прокатит Dim C[15]. В Паскале тоже есть array[0..14] of Char и на него с легкостью можно ссылаться как к PChar. Только заканчиваться такая строка должна символом с кодом 0. Или передавать в ином случае реальное количество символов.
← →
Digitman (2003-04-28 14:15) [48]
> evvcom
гадать на кофейной гуще можно сколько угодно)
при наличии определенных знаний можно и без документации выяснить, что в реальности передает Фокс в том или ином случае...
но, к сож., ни автор ни его Фокс-коллега такими знаниями не обладают..
а по поводу "В Паскале тоже есть array[0..14] of Char" скажу лишь, что не следует сравнивать яз.среды разных типов - компилирующие и интерпретирующие... в последних все переменные - динамические, в то время как упомянутая конструкция Паскаля резервирует статическую область памяти
← →
ErikIvanov (2003-04-28 14:22) [49]Незнаю как в новом FoxPro под windows, но в старом до 2.5 нельзя было загружать обычную Dll. Но можно было создовать модули на WatCom C в спецальном формате. После мелкософт прикуил FoxPro и сделал версию под Windows. Наверника предусмотрел загрузку dll. И сделл это наверно стандартно использовав готовый код. Значить при передаче параметров любым способом их можно прочесть! Значить можно попробовать сделать небольшой тест. Передой в Fox один параметр. И ShareMem разумеется убери.
← →
evvcom (2003-04-28 14:25) [50]
> Digitman © (28.04.03 14:15)
> гадать на кофейной гуще можно сколько угодно
Полностью согласен.
← →
Digitman (2003-04-28 14:35) [51]
> Наверника предусмотрел загрузку dll
И наверняка - есть документация ! Которая предназначена для чтения, а не для покрытия пылью)
← →
Anatoly Podgoretsky (2003-04-28 14:41) [52]Digitman © (28.04.03 14:15)
А еще добавлю, приходилось разбираться с Фоксом, там вообще нет переменных, есть структура в 56 байт - дескриптор, в которой содержится все необходимое, включая тип, имя, описание и прочее.
И все это хорошо документировано, включая связь с другими языками и библиотеками.
← →
Digitman (2003-04-28 14:56) [53]
> Anatoly Podgoretsky
> там вообще нет переменных
ну так, думаю, тоже говорить нельзя)
переменная в любой языковой среде прогр-я всегда останется переменной, а по поводу того, как это представлено в памяти - разумеется, в интерпретирующих средах динамически распределяемые структуры данных всегда описываются дескрипторами ! иначе - как без дескрипторов организовать хотя бы те же неявные преобразования типов ?
← →
Петр (2003-04-29 09:01) [54]Случилось событие !!! Написал я наконец DLL, в Fox"e работает и воспринимает мои функции.
Решение оказалось простым (DigitMan"у особое спасибо): вместо входных и выходных параметров String заменил на PChar.
В Fox"e на вход моих функций предается String, а на выходе в своих функциях DLL я возвращаю PChar. По крайней мере реализация такого варианта прошла без ошибок.
СПАСИБО ВСЕМ, КТО ПРИНЯЛ УЧАСТИЕ В ОБСУЖДЕНИИ ДАННОГО ВОПРОСА
С уважением,
Петр.
Страницы: 1 2 вся ветка
Форум: "Основная";
Текущий архив: 2003.05.12;
Скачать: [xml.tar.bz2];
Память: 0.59 MB
Время: 0.01 c