任何人都知道如何在DLL中创建单词ole对象吗。我有一个应用程序,它加载一个DLL,然后创建单词ole对象。我的应用程序每次都会崩溃。
MSWord:= CreateOleObject('Word.Application');
假设Word已安装,那么代码可能失败的主要原因是COM尚未在调用线程中初始化。这不应该从DLL中尝试,因为您希望DLL能够与已经初始化COM.的使用者一起工作
因此,解决此问题的正确方法是作为DLL接口约定的一部分声明COM必须由调用方初始化。通常通过调用CCD_ 1或CCD_。
另一个注释是,如果应用程序崩溃,则表明错误处理已损坏。DLL中的所有函数都应该采取步骤来捕获任何异常,并转换为返回给调用方的错误代码。我怀疑您没有这样做,并且正在从DLL中抛出一个Delphi异常。你决不能那样做。
请注意,我已经给出了一个广泛而笼统的答案。这与问题的广泛性质以及问题中几乎没有细节的事实相匹配。如果您提供了MCVE,我们本可以提供更详细的回复。
正如DavidH所指出的,CoInitialize必须在调用线程中调用。
关于VCL应用程序的主线程,需要注意的一点是,VCL应用是否自动调用CoInitialize取决于它是否使用ComObj单元:如果使用了,则通过TApplication.Initialize和ComObj中的InitComObj例程调用CoInitialize:;如果没有,则必须自己调用它(或CoInitializeEx)。
测试这一点的简单方法是从一个没有应用程序的控制台应用程序调用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.