繁体   English   中英

Delphi单词自动化:在Dll中创建Ole对象

[英]Delphi word automation: Create Ole Object inside Dll

是否有人知道如何在DLL中创建ole对象。 我有一个加载DLL的应用程序,该DLL又创建了ole对象。 每次我的应用程序崩溃。

MSWord:= CreateOleObject('Word.Application');

假定已安装Word,则您的代码可能失败的主要原因是未在调用线程中初始化COM。 那不是应该从DLL尝试的事情,因为您希望DLL能够与已经初始化COM的使用者一起使用。

因此,解决此问题的正确方法是将DLL声明为DLL接口协定的一部分,而调用者必须初始化COM。 通常通过调用CoInitializeCoInitializeEx

另一条评论是,如果应用程序崩溃,则表明您的错误处理已损坏。 DLL中的所有函数都应采取步骤以捕获任何异常并将其转换为错误代码以返回给调用者。 我怀疑您尚未执行此操作,并且正在从DLL中抛出Delphi异常。 你绝对不能那样做。

请注意,我给出了广泛而笼统的答案。 这与问题的广泛性质以及问题中几乎没有细节的事实相吻合。 如果您提供了MCVE,我们可以提供更详细的答复。

正如DavidH所指出的,必须在调用线程中调用CoInitialize。

与VCL应用程序的主线程有关的注意点是,VCL应用程序是否自动调用CoInitialize取决于它是否使用ComObj单元:如果是,则通过TApplication.Initialize和InitComObj例程调用CoInitialize。 ComObj; 如果不是,则必须自己调用(或CoInitializeEx)。

测试此问题的简单方法是从一个不带TApplication的控制台应用程序中调用DLL-这样可以避免被ComObj误用,而不是使用您的主机。

假设您有一个包含以下导出过程的DLL:

procedure CreateWordDoc;
var
  DocText : String;
  MSWord,
  Document : OleVariant;
begin
  MSWord := CreateOleObject('Word.Application');
  MSWord.Visible := True;
  Document := MSWord.Documents.Add;
  DocText := 'Hello Word!';
  MSWord.Selection.TypeText(DocText);
end;

那么您可以这样称呼它:

program WordCaller;

{$APPTYPE CONSOLE}

uses
  SysUtils, Windows, ActiveX;

type
  TWordProc = procedure;

var
  LibHandle : THandle;
  WordProc : TWordProc;
begin
  CoInitialize(Nil);
  LibHandle := LoadLibrary('WordDll.Dll');
  try
    if LibHandle <> 0 then begin
      try
        WordProc := GetProcAddress(LibHandle, 'CreateWordDoc');
         if Assigned(WordProc) then
             WordProc;
       finally
         FreeLibrary(LibHandle);
       end;
    end;
  finally
    CoUnInitialize;
    Readln;
  end;
end.

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM