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

Вниз

dll c точкой входа для DllRegisterServer   Найти похожие ветки 

 
avtolik   (2004-12-28 08:43) [0]

возникла проблема. Написал dll-шку, которую использую в надстройках для Excel-а. В общем в ХР=шном Экселе не вызываются функции из этой длл-шки. Из 2000 Офисов и ниже все работает Ок, а из ХР нифига. Мысль была такая, что надо длл-шку зарегистрировать. Так вот при регистрации выходит сообщение, что не найдена точка входа для DllRegisterServer. Посоветуйте чего-нибудь.


 
Digitman ©   (2004-12-28 08:48) [1]

т.е. в ДЛЛ ты реализовал олей-сервер автоматизации ? я правильно понял ?


 
avtolik   (2004-12-28 09:46) [2]

да нет. В ДЛЛ-шке написал математическую функцию (там обрабатываются данные из базы данных, поэтому и использовал делфю). В Экселе (в VB) сделал надстройку, в которой и вызывается эта функция. Видишь ли, все работало нормально, пока не поставили Офис ХР. Причем удаляешь этот офис, ставишь 2000-ый и все-равно ничего не работает. Переустанавливаешь систему, ставишь 2000-ый Офис и только тогда все опять работает. Система: Винда ХР. Я и подумал про регистрацию длл-шки. Может я не прав и дело в другом?


 
Digitman ©   (2004-12-28 09:50) [3]


> Я и подумал про регистрацию длл-шки


если длл не являет собой сервер автоматизации, то никакая регистрация не нужна

покажи код длл и пример обращения к ней из VB


 
avtolik   (2004-12-28 11:26) [4]

Вот ДЛЛ-ка:

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

Повторюсь, все работало в офисах ниже ХР. Функцию из ДЛЛ вызывал и из проги написаной на самой делфе. Работает.


 
avtolik   (2004-12-28 11:30) [5]

Пардон, строчка R = 10.12 лишняя (засобачил по ошибке)


 
Digitman ©   (2004-12-28 12:07) [6]

так, понятно.
а что значит "не работает" ?
в чем и как это реально проявляется ?
пошаговую трассировку кода библиотеки делал ?


 
avtolik   (2004-12-28 14:59) [7]

Не работает - это значит что функция mRezMan просто не вызывается. В длл-шке может быть вообще любой код (mRezMan := 100). Не возвращает она ничего. В коде на VB в месте вызова mRezMan все просто останавливается и все.


 
Digitman ©   (2004-12-28 15:24) [8]

пошаговую трассировку кода библиотеки делал ?


 
avtolik   (2004-12-29 06:57) [9]

Я же тебе говорю все работало раньше. Можно написать прогу на делфях с вызовом этой функции из ДЛЛ. Все будет работать и считать. Как еще проверить то? Можно всю функцию mRezMan из этой ДЛЛ заменить одной строчкой, например (как я уже писал), mRezMan=100. Она опять же будет везде работать, но только на из Офисов ХР. Есть еще какое-нибудь предложение?


 
Shaman_Naydak   (2004-12-29 07:03) [10]

настройки безопасности?


 
Digitman ©   (2004-12-29 08:04) [11]


> avtolik   (29.12.04 06:57) [9]
> Я же тебе говорю все работало раньше


да мало чего работало раньше !

трассировка кода иниц-ции даст тебе по крайней мере возможность узнать, загружается ЛИ и инициализируется ЛИ в принципе твоя библиотека .. от этого и плясать надо !


 
avtolik   (2004-12-29 08:13) [12]

Так, я уже не врубаюсь. Я могу трасировать библиотеку из той же делфы. Но я уже пару раз писал, что в этом случае все запускается и работает(см. раньше). А как мне трассировать ее конкретно для VB (в нем я еще хуже чем в делфе)? Как раз для него то, мне кажется, длл даже и не инициализируется (?).

Для Shaman_Naydak. Настройка безопасности (в Excel-е) = низкий уровень. Что-то еще есть: где и как?


 
Digitman ©   (2004-12-29 08:35) [13]


> как мне трассировать ее конкретно для VB


VB ведь реализован в контексте обычного Win32-приложения
для трассировки кода библиотеки

см. Run -> Parameters -> Local -> Host Application = "dev:\path\excel.exe"

ставишь брейкпойнт в коде иниц-ции своей библиотеки, жмешь Ф9, Ексель стартует, в какой-то момент времени грузит твою библиотеку, и в этот момент ты ловишь свой ьрейк ... далее - все как обычно


 
Digitman ©   (2004-12-29 08:51) [14]


> Как раз для него то, мне кажется, длл даже и не инициализируется
> (?).


если такое подозрение у тебя существует даже без трассировочной проверки, то это скорей всего означает, что указанная тобой в 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:57) [15]


> avtolik   (29.12.04 08:13) [12]


вот хотя бы для того чтобы никак не зависеть от фактического расширения имени, местоположения библ-ки и регистра в именах эксп.вызовов и желательно реализовывать подобного рода библ."надстройки" не в виде обычных ДЛЛ, а в виде олей-серверов автоматизации


 
avtolik   (2004-12-29 13:05) [16]

спасибо за советы. Попробую помучиться еще.



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

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

Наверх




Память: 0.53 MB
Время: 0.027 c
14-1103879678
Кудесник
2004-12-24 12:14
2005.01.16
Лечится или нет?


1-1104841892
frEE)stylEr
2005-01-04 15:31
2005.01.16
DLL


14-1104320614
TUser
2004-12-29 14:43
2005.01.16
Есть ли такой эксперт


1-1103895082
XfroSt
2004-12-24 16:31
2005.01.16
как определить имя пользователя


1-1103581432
GanibalLector
2004-12-21 01:23
2005.01.16
PCHAR