Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > IT форум > Помощь студентам
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 29.12.2018, 20:18   #1
KBO
Форумчанин
 
Регистрация: 11.06.2010
Сообщений: 525
По умолчанию Delphi 10.2 - system exception – с переносом кода в библиотеку

Доброе время суток форумчане
Есть следующий код который просто читает word файл и его сохраняет, а потом открывает – все хорошо работало, но после переноса строк кода (работы с документом word)

Код:
Words_Templs: variant;

implementation

{$R *.dfm}

function CreateWord: boolean;
//create word application
begin
  CreateWord := true;
  try
    Words_Templs := CreateOleObject('Word.Application');
  except
    begin
//      showmessage('Пакет Microsoft Office не найден');
      Application.MessageBox('', 'Warning', MB_OK+MB_ICONEXCLAMATION);
      CreateWord := false;
    end;
  end;
End;

function Open_Doc_Template(APath_file: string): boolean;
//open template file
var
  LDoc: variant;
begin
CreateWord;
  Open_Doc_Template := true;
  try
    LDoc := Words_Templs.Documents;
    LDoc.Open(APath_file);
  except
    Open_Doc_Template := false;
  end;
End;

function CloseDoc:boolean;
begin
  CloseDoc := true;
  try
    Words_Templs.ActiveDocument.Close;
  except
    CloseDoc := false;
  end;
end;

function Close_Document(AMode: integer): boolean; export;
{close document
0 - MS Word
1 - MS Excel}
begin
  if AMode = 0 then
  begin
    Close_Document := true;
    try
      Words_Templs.Quit;
      except
        Close_Document := false;
    end;
  end
end;

procedure OPEN_MAKE_DOC(ANamePath, ANameFile, ATypeFiles: string;
                        AMode: integer; var APathFile: string); export;
//open make document
{LNameFile - name file + extension file}
{LMode
0 - without open dialog window
1 - with open dialog window}
var
  handle: hwnd;
begin
  case AMode of
    0: shellexecute(handle,'open',pchar(ANamePath+'result_doc.rtf'),'','',1);
  end;
end;

function SaveDocAs(ANamePath, ANameFile: string; AOpenDoc: integer):boolean; export;
//save created doc
{
LOpenDoc
  0 - not open created doc
  1 - open created doc
}
var
  LPath: string;
begin
  SaveDocAs := true;
  try
    begin
      Words_Templs.ActiveDocument.SaveAs(ANamePath+'result_doc.rtf');
      CloseDoc;
      Close_Document(0);
      if AOpenDoc = 1 then
        OPEN_MAKE_DOC(ANamePath, 'result_doc.rtf', '', 0, LPath);
    end;
  except
    SaveDocAs := false;
  end;
end;
в библиотеку и закрытия приложения (вызвавшую dll) которое удачно прочитало и пересохранило файл, в режиме ОТЛАДКИ, стала возникать ошибка:

Debugger Fault Notification
---------------------------
Project D:\Prog\_Example\Example application\PEx_application.exe faulted with message: 'system exception (code 0xc000000d) at 0x77417fdc'. Process Stopped. Use Step or Run to continue.
---------------------------

Приложение (вызвавшее dll)

Код:
 procedure Open_Doc_Template(LPath_file: string); far; external 'SPF';
  function SaveDocAs(LNamePath, LNameFile: string;
                               LOpenDoc: integer):boolean; far; external 'SPF';

procedure TForm2.Button1Click(Sender: TObject);
begin
  Open_Doc_Template(ExtractFileDir(application.ExeName)+'\Template\Template_example.rtf');
  SaveDocAs(ExtractFileDir(application.ExeName)+'\Result output\', 'result_doc.rtf', 1);
end;
В режиме простого запуска и закрытия приложения, после его закрытия, что-то секунду происходит конечно, но в конце концов все заканчивается удачно.

Что может быть не так?
Заранее спасибо.

Последний раз редактировалось KBO; 29.12.2018 в 23:08.
KBO вне форума Ответить с цитированием
Старый 29.12.2018, 23:25   #2
Terran
Участник клуба
 
Аватар для Terran
 
Регистрация: 28.11.2007
Сообщений: 1,521
По умолчанию

При работе с dll могут возникать сложности. Перед вызовом функций для работы с COM объектами используйте CoInitialize(Nil) и CoUninitialize соответственно. Исключения составляет функция CoGetMalloc и функции выделения памяти.

P.S. CoInitialize(Nil) достаточно вызвать один раз при инициализации dll.
Всегда рад помочь!
Terran вне форума Ответить с цитированием
Старый 29.12.2018, 23:33   #3
KBO
Форумчанин
 
Регистрация: 11.06.2010
Сообщений: 525
По умолчанию

Ставил,

Код:
procedure Open_Doc_Template(LPath_file: string); far; external 'SPF';
  function SaveDocAs(LNamePath, LNameFile: string;
                               LOpenDoc: integer):boolean; far; external 'SPF';

procedure TForm2.Button1Click(Sender: TObject);
begin
CoInitialize(Nil);  Open_Doc_Template(ExtractFileDir(application.ExeName)+'\Template\Template_example.rtf');
  SaveDocAs(ExtractFileDir(application.ExeName)+'\Result output\', 'result_doc.rtf', 1);
CoUninitialize;
end;
Но ошибка не уходит
KBO вне форума Ответить с цитированием
Старый 30.12.2018, 00:24   #4
Terran
Участник клуба
 
Аватар для Terran
 
Регистрация: 28.11.2007
Сообщений: 1,521
По умолчанию

Попробуйте без CoUninitialize. Функцию инициализации лучше вызывать непосредственно в dll.
Всегда рад помочь!
Terran вне форума Ответить с цитированием
Старый 30.12.2018, 00:32   #5
KBO
Форумчанин
 
Регистрация: 11.06.2010
Сообщений: 525
По умолчанию

Указал в

Код:
function Open_Doc_Template(APath_file: string): boolean; export;
//open template file
var
  LDoc: variant;
begin
  CoInitialize(nil);
  CreateWord;
  ....
не помогает,
P.S.
("SharaMem" - указаны в обоих проектах)
KBO вне форума Ответить с цитированием
Старый 30.12.2018, 01:03   #6
Terran
Участник клуба
 
Аватар для Terran
 
Регистрация: 28.11.2007
Сообщений: 1,521
По умолчанию

Цитата:
Сообщение от KBO Посмотреть сообщение
не помогает
Я собрал проект в Delphi 10.2. У меня работает... Вы точно везде убрали CoUninitialize?
Напишите в dll'ке так:
Код:
...
begin
  CoInitialize(Nil)

end.
Всегда рад помочь!
Terran вне форума Ответить с цитированием
Старый 30.12.2018, 02:32   #7
KBO
Форумчанин
 
Регистрация: 11.06.2010
Сообщений: 525
По умолчанию

действительно правы, работает даже без "CoInitialize(Nil)".
Значит дело в другом, у меня библиоте много процедур и функций.
Я тут привел только то, что касается непосредственно Word.

Интересно...
KBO вне форума Ответить с цитированием
Старый 30.12.2018, 10:45   #8
KBO
Форумчанин
 
Регистрация: 11.06.2010
Сообщений: 525
По умолчанию

Разобрался, да не совсем.
Если эти функции в одном модуле библиотеки - то все работает.
Но у меня все разбросано по двум модулям.
В первом модуле:
CreateWord, Open_Doc_Template, CloseDoc.

Во втором модуле:
OPEN_MAKE_DOC, SaveDocAs, Close_Document

значит собака где-то в этом месте зарыта...

т.е. поправка, если все функции в *dpr*, то все работает, А если в двух *pas*, то - ошибка

Последний раз редактировалось KBO; 30.12.2018 в 10:59.
KBO вне форума Ответить с цитированием
Старый 30.12.2018, 12:52   #9
Terran
Участник клуба
 
Аватар для Terran
 
Регистрация: 28.11.2007
Сообщений: 1,521
По умолчанию

Цитата:
Сообщение от KBO Посмотреть сообщение
Если эти функции в одном модуле библиотеки - то все работает.
Но у меня все разбросано по двум модулям.
Попробовал два варианта. У меня всё ок. Если есть возможность, выложите проект в архиве. Будет проще разобраться.

P.S. Отходя от основного вопроса дам несколько советов:
1. Используйте Result для указания результата выполнения функций (будет универсально, проще, понятно);
2. Старайтесь явно указывать соглашения о вызове функций, поможет избежать потенциальных ошибок;
3. В процедуре OPEN_MAKE_DOC при вызове shellexecute у вас передаётся не проинициализированный handle (лучше такое имя для переменной не использовать);
4. При указании библиотеки (external 'SPF') старайтесь писать имена целиком ('SPF.dll');
5. Лучше не использовать тип данных string при экспорте функций т.к. это внутренний тип данных Delphi и при подключении библиотеки к программе написанной на другом языке будут проблемы;
...
Всегда рад помочь!
Terran вне форума Ответить с цитированием
Старый 30.12.2018, 13:33   #10
KBO
Форумчанин
 
Регистрация: 11.06.2010
Сообщений: 525
По умолчанию

Спасибо за советы Terran.
вот dll c программой ссылка
{Кажется нашел проблему, я в одном из модулей dll (а именно в "UDoc.pas") подключаю "Vcl.DBGrids;" - и когда я его подключаю возникает ошибка, как ее добиться описал ниже}
посмотрите пожалуйста

1 запускаете программу (в delphi)
2 нажимаете кнопку (появляется документ word)
3 закрываете документ word
4 закрываете программу и должна выскочить ошибка

Цитата:
Сообщение от Terran Посмотреть сообщение
В процедуре OPEN_MAKE_DOC при вызове shellexecute у вас передаётся не проинициализированный handle (лучше такое имя для переменной не использовать);
Насчет этого, в help по "shellexecute" (- что это хендл родительского окна), как проинициализировать handle, если в dll даже окна нет? Или сюда нужно передавать тогда дескриптор окна вызывающего приложения?

Последний раз редактировалось KBO; 30.12.2018 в 16:14.
KBO вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Проблема с переносом кода с С++ на С# (Машина Тьюринга) Konark C# (си шарп) 3 19.02.2015 17:26
Проблемы с переносом кода с Delphi 7 на Delphi XE2 MORPEH Общие вопросы Delphi 1 05.08.2013 14:09
При выполнение кода выводится Debugger exception notification sasha198407 БД в Delphi 0 31.03.2012 11:50
ошыбка unhandled exception of type 'system.argumentNullexception' occurred in mscorlib.dll Pein95 C# (си шарп) 3 10.08.2011 11:04
ошыбка Project vk_id.exe raised exception class eoserror with message System error Pein95 Общие вопросы Delphi 6 17.06.2011 20:38