Форум: "Основная";
Текущий архив: 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