![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
dll c точкой входа для DllRegisterServer
avtolik © (2004-12-28 08:43:00)возникла проблема. Написал dll-шку, которую использую в надстройках для Excel-а. В общем в ХР=шном Экселе не вызываются функции из этой длл-шки. Из 2000 Офисов и ниже все работает Ок, а из ХР нифига. Мысль была такая, что надо длл-шку зарегистрировать. Так вот при регистрации выходит сообщение, что не найдена точка входа для DllRegisterServer. Посоветуйте чего-нибудь.
avtolik (2004-12-29 13:05:00) [1]спасибо за советы. Попробую помучиться еще.
Digitman (2004-12-29 08:57:00) [2]
> avtolik (29.12.04 08:13) [12]
вот хотя бы для того чтобы никак не зависеть от фактического расширения имени, местоположения библ-ки и регистра в именах эксп.вызовов и желательно реализовывать подобного рода библ."надстройки" не в виде обычных ДЛЛ, а в виде олей-серверов автоматизации
Digitman (2004-12-29 08:51:00) [3]
> Как раз для него то, мне кажется, длл даже и не инициализируется
> (?).
если такое подозрение у тебя существует даже без трассировочной проверки, то это скорей всего означает, что указанная тобой в VB-коде твоя библиотека попросту не найдена ядром VB-интерпретатора
мне, например, в твоей декларации
Public Declare Function mRezMan Lib " manom" (ByVal Year As Long, ByVal ManomNumber As Long, ByVal C As Double, ByVal PBar As Double, ByVal NAvg As Double) As Double
сильно не нравится то что в имени файла библ-ки не указано его расширение.. к тому же алгоритмы поиска библ.файла (в путях по умолчанию) у различных версий Офиса вполне могут отличаться, поэтому фактическое месторасположение библ.файла в случае неуказания ни абсолютного ни относительного путей к нему может быть критичным
p.s.
спецификатор far можно смело убрать из деклараций в Делфи-коде библ-ки - вызовы ВСЕХ п/программ, точки входа в которые экспортируются тобой, иначе как дальними быть не могут, т.е. они far по дифолту
Digitman (2004-12-29 08:35:00) [4]
> как мне трассировать ее конкретно для VB
VB ведь реализован в контексте обычного Win32-приложения
для трассировки кода библиотеки
см. Run -> Parameters -> Local -> Host Application = "dev:\path\excel.exe"
ставишь брейкпойнт в коде иниц-ции своей библиотеки, жмешь Ф9, Ексель стартует, в какой-то момент времени грузит твою библиотеку, и в этот момент ты ловишь свой ьрейк ... далее - все как обычно
avtolik (2004-12-29 08:13:00) [5]Так, я уже не врубаюсь. Я могу трасировать библиотеку из той же делфы. Но я уже пару раз писал, что в этом случае все запускается и работает(см. раньше). А как мне трассировать ее конкретно для VB (в нем я еще хуже чем в делфе)? Как раз для него то, мне кажется, длл даже и не инициализируется (?).
Для Shaman_Naydak. Настройка безопасности (в Excel-е) = низкий уровень. Что-то еще есть: где и как?
Digitman (2004-12-29 08:04:00) [6]
> avtolik (29.12.04 06:57) [9]
> Я же тебе говорю все работало раньше
да мало чего работало раньше !
трассировка кода иниц-ции даст тебе по крайней мере возможность узнать, загружается ЛИ и инициализируется ЛИ в принципетвоя библиотека .. от этого и плясать надо !
Shaman_Naydak (2004-12-29 07:03:00) [7]настройки безопасности?
avtolik (2004-12-29 06:57:00) [8]Я же тебе говорю все работало раньше. Можно написать прогу на делфях с вызовом этой функции из ДЛЛ. Все будет работать и считать. Как еще проверить то? Можно всю функцию mRezMan из этой ДЛЛ заменить одной строчкой, например (как я уже писал), mRezMan=100. Она опять же будет везде работать, но только на из Офисов ХР. Есть еще какое-нибудь предложение?
Digitman (2004-12-28 15:24:00) [9]пошаговую трассировку кода библиотеки делал ?
avtolik (2004-12-28 14:59:00) [10]Не работает - это значит что функция mRezMan просто не вызывается. В длл-шке может быть вообще любой код (mRezMan := 100). Не возвращает она ничего. В коде на VB в месте вызова mRezMan все просто останавливается и все.
Digitman (2004-12-28 12:07:00) [11]так, понятно.
а что значит "не работает" ?
в чем и как это реально проявляется ?
пошаговую трассировку кода библиотеки делал ?
avtolik (2004-12-28 11:30:00) [12]Пардон, строчка R = 10.12 лишняя (засобачил по ошибке)
avtolik (2004-12-28 11:26:00) [13]Вот ДЛЛ-ка:
library Manom;
{$S-}
uses
BDE, Dialogs,
Windows,
SysUtils,
INIFiles,
DMUnit in 'DMUnit.pas' {DataModule1: TDataModule};
{$R *.RES}
var
SaveExit: Pointer;
procedure LibExit; far;
begin
if ExitCode > 0 then
begin
{ System shutdown in progress }
end else
begin
{ DLL is unloaded }
end;
ExitProc := SaveExit;
end;
function mOpenINIFile : TIniFile;
var Buffer : String[255];
begin
SetLength(Buffer, 'd:\windows\system'{GetSystemDirectory(@Buffer[1], SizeOf(Buffer)));
Result := TIniFile.Create({Buffer + 'manom.ini');
end;
//Эта та функция ради которой все и затевалось
function mRezMan(Year, ManomNumber : Integer; C, PBar, NAvg : Double) : Double;{far; export;}stdcall;
var F : TIniFile;
DataBaseName, YearStr : String;
K, Dnt : Extended;
NcpLeft, NcpRight : Extended;
DntLeft, DntRight : Extended;
Popal1, Popal2 : Boolean;
begin
DataModule1 := TDataModule1.Create(nil);
YearStr := IntToStr(Year);
F := mOpenINIFile;
try
DataBaseName := F.ReadString('General', 'DataBaseName', '');
finally
F.Free;
end;
{ Генерируем имена базы данных }
DataModule1.Manom.DatabaseName := DataBaseName;
DataModule1.Pokaz.DatabaseName := DataBaseName;
{ Формирование имен нужных таблиц за нужные года }
DataModule1.Pokaz.TableName := 'pokaz_m' + YearStr;
try
{ Открытие базы }
DataModule1.Manom.Open;
try
DataModule1.Pokaz.Open;
try
{ Связываем нужные таблицы }
DataModule1.Pokaz.MasterSource := DataModule1.DSManom;
DataModule1.Pokaz.MasterFields := 'ZAV_NOM';
DataModule1.Manom.SetKey;
DataModule1.ManomZav_Nom.AsInteger := ManomNumber;
if DataModule1.Manom.GotoKey then
begin
K := DataModule1.ManomPerev_Koef.AsFloat;
NcpLeft := -1e100;
NcpRight := 1e100;
DntLeft := 0;
DntRight := 0;
{ Вспомогательные флажки: нашли ли мы нужный диапазон в следующем цикле? }
Popal1 := false;
Popal2 := false;
DataModule1.Pokaz.First;
{ Цикл по свойствам текущего манометра, если все необходимые данные заданы }
if DataModule1.Pokaz.RecordCount > 0 then
begin
while not DataModule1.Pokaz.EOF do
begin
{ Вычисление ближайшей правой границы }
if (DataModule1.PokazNcp.AsFloat < NcpRight) and
(DataModule1.PokazNcp.AsFloat >= NAvg) then
begin
NcpRight := DataModule1.PokazNcp.AsFloat;
DntRight := DataModule1.PokazDnt.AsFloat;
Popal1 := true;
end;
{ Вычисление ближайшей левой границы }
if (DataModule1.PokazNcp.AsFloat > NcpLeft) and
(DataModule1.PokazNcp.AsFloat <= NAvg) then
begin
NcpLeft := DataModule1.PokazNcp.AsFloat;
DntLeft := DataModule1.PokazDnt.AsFloat;
Popal2 := true;
end;
DataModule1.Pokaz.Next;
end; // Проход по свойствам для вычисления min / max значений
end else
begin
{ Таблица тарировок пуста для данного манометра }
Result := 35e30;
Exit;
end;
{ Если нашли диапазон, вычисляем }
if Popal1 and Popal2 then
begin
if NcpRight = NcpLeft
then Dnt := (DntLeft + DntLeft) / 2
else Dnt := (NAvg - NcpLeft) * (DntRight - DntLeft) / (NcpRight - NcpLeft) + DntLeft;
{ Все зашибись }
{ MessageDlg('Dnt left: ' + FloatToStr(DntLeft) + #13 +
'Dnt right: ' + FloatToStr(DntRight) + #13 +
'Ncp left: ' + FloatToStr(NcpLeft) + #13 +
'Ncp right: ' + FloatToStr(NcpRight) + #13 +
'Dnt: ' + FloatToStr(Dnt) + #13 +
'NAvg: ' + FloatToStr(NAvg) + #13 +
'K: ' + FloatToStr(K) + #13 +
'', mtInformation, [mbOk], 0); }
Result := (NAvg + Dnt) * K + PBar + C;
Exit;
end else
begin
{ Не попали ни в один из диапазонов тарировок для указанного манометра }
Result := 25e30;
Exit;
end; // Проверка на существование корректных данных в текущей записи в Sredn
end else
begin
{ Манометра с указанным заводским номером не существует }
Result := 15e30;
Exit;
end;
{ Убираем настроенные ранее связи }
DataModule1.Manom.MasterSource := nil;
DataModule1.Manom.MasterFields := '';
DataModule1.Pokaz.MasterSource := nil;
DataModule1.Pokaz.MasterFields := '';
finally
{ Закрываем БД }
DataModule1.Pokaz.Close;
end;
finally
{ Закрываем БД }
DataModule1.Manom.Close;
end;
except
{ Ошибка открытия/чтения }
Result := 45e30;
Exit;
end;
DataModule1.Free;
end;
exports
mRezMan index 1;
begin
SaveExit := ExitProc;
ExitProc := @LibExit;
end.
А вот как я использую ее в VB
Public Declare Function mRezMan Lib "manom" (ByVal Year As Long, ByVal ManomNumber As Long, ByVal C As Double, ByVal PBar As Double, ByVal NAvg As Double) As Double
'Вот эту функцию уже конкретно применяю для расчета в Excel-е
Public Function RezMan(ByVal Year As Long, ByVal ManomNumber As Long, ByVal C As Double, ByVal PBar As Double, ByVal NAvg As Double) As String
R = mRezMan(Year, ManomNumber, C, PBar, NAvg)
R = 10.12
Rez = Format(R, "0.########")
If (R > 3.4999E+31) And (R < 3.5001E+31) Then Rez = "Таблица тарировок указанного манометра пуста"
If (R > 2.4999E+31) And (R < 2.5001E+31) Then Rez = "Не попали ни в один из диапазонов"
If (R > 1.4999E+31) And (R < 1.5001E+31) Then Rez = "Манометра с указанным номером не существует"
RezMan = Rez
End Function
Повторюсь, все работало в офисах ниже ХР. Функцию из ДЛЛ вызывал и из проги написаной на самой делфе. Работает.
Digitman (2004-12-28 09:50:00) [14]
> Я и подумал про регистрацию длл-шки
если длл не являет собой сервер автоматизации, то никакая регистрация не нужна
покажи код длл и пример обращения к ней из VB
avtolik (2004-12-28 09:46:00) [15]да нет. В ДЛЛ-шке написал математическую функцию (там обрабатываются данные из базы данных, поэтому и использовал делфю). В Экселе (в VB) сделал надстройку, в которой и вызывается эта функция. Видишь ли, все работало нормально, пока не поставили Офис ХР. Причем удаляешь этот офис, ставишь 2000-ый и все-равно ничего не работает. Переустанавливаешь систему, ставишь 2000-ый Офис и только тогда все опять работает. Система: Винда ХР. Я и подумал про регистрацию длл-шки. Может я не прав и дело в другом?
Digitman (2004-12-28 08:48:00) [16]т.е. в ДЛЛ ты реализовал олей-сервер автоматизации ? я правильно понял ?