Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 2005.01.16;
Скачать: [xml.tar.bz2];

Вниз

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;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.52 MB
Время: 0.067 c
1-1104128308
Pavelkq
2004-12-27 09:18
2005.01.16
TFileStream.Create или еще чего?


14-1104232305
syte_ser78
2004-12-28 14:11
2005.01.16
вопрос по Magiс Forum 1.2


14-1104049679
Fin
2004-12-26 11:27
2005.01.16
Расчет платежа за электроэнергию.


1-1104239927
Anonimus
2004-12-28 16:18
2005.01.16
Картинки


14-1104073570
Михайло
2004-12-26 18:06
2005.01.16
Где в Самаре





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский