zig*_*zig 4 delphi dll winapi multithreading delphi-7
继续我的另一个问题: 如何从我的应用程序传递和检索内存流到/从DLL?
我用IStream
输入/输出编写了DLL .DLL使用IXMLDocument
(起初我认为与后续问题有关)测试它,它在主UI中运行良好.当我从工作线程调用DLL时出现问题.
DLL:
library MyDLL;
uses
Windows,
Variants,
SysUtils,
Classes,
AxCtrls,
ActiveX,
XMLDoc,
XMLIntf;
{$R *.res}
procedure Debug(V: Variant);
begin
OutputDebugString(PChar(VarToStr(V)));
end;
procedure DoProcess(InStream, OutStream: TStream);
var
Doc: IXMLDocument;
begin
InStream.Position := 0;
Doc := TXMLDocument.Create(nil);
Doc.LoadFromStream(InStream);
// plans to do some real work...
OutStream.Position := 0;
Debug('MyDLL DoProcess OK');
end;
function Process(AInStream, AOutStream: IStream): Integer; stdcall;
var
InStream, OutStream: TStream;
begin
try
InStream := TOleStream.Create(AInStream);
try
OutStream := TOleStream.Create(AOutStream);
try
DoProcess(InStream, OutStream);
Result := 0;
finally
OutStream.Free;
end;
finally
InStream.Free;
end;
except
on E: Exception do
begin
Result := -1;
Debug('MyDLL Error: ' + E.Message);
end;
end;
end;
exports
Process;
begin
end.
Run Code Online (Sandbox Code Playgroud)
我的来电申请:
implementation
uses
ActiveX,ComObj;
{$R *.dfm}
procedure Debug(V: Variant);
begin
OutputDebugString(PChar(VarToStr(V)));
end;
const
MyDLL = 'MyDLL.dll';
{$DEFINE STATIC_DLL}
{$IFDEF STATIC_DLL}
function Process(AInStream, AOutStream: IStream): Integer; stdcall; external MyDLL;
{$ENDIF}
type
// Dynamic
TDLLProcessProc = function(AInStream, AOutStream: IStream): Integer; stdcall;
function DLLProcess(AInStream, AOutStream: TStream): Integer;
var
InStream, OutStream: IStream;
Module: HMODULE;
DLLProc: TDLLProcessProc;
begin
InStream := TStreamAdapter.Create(AInStream, soReference);
OutStream := TStreamAdapter.Create(AOutStream, soReference);
{$IFDEF STATIC_DLL}
Result := Process(InStream, OutStream); // Static
Exit;
{$ENDIF}
// Dynamic load DLL ...
Module := LoadLibrary(MyDLL);
if Module = 0 then RaiseLastOSError;
try
DLLProc := GetProcAddress(Module, 'Process');
if @DLLProc = nil then RaiseLastOSError;
Result := DLLProc(InStream, OutStream);
finally
FreeLibrary(Module);
end;
end;
type
TDLLThread = class(TThread)
private
FFileName: string;
public
constructor Create(CreateSuspended: Boolean; AFileName: string);
procedure Execute(); override;
end;
constructor TDLLThread.Create(CreateSuspended: Boolean; AFileName: string);
begin
FreeOnTerminate := True;
FFileName := AFileName;
inherited Create(CreateSuspended);
end;
procedure TDLLThread.Execute;
var
InStream, OutStream: TMemoryStream;
RetValue: Integer;
begin
try
//CoInitializeEx(nil, COINIT_APARTMENTTHREADED);
CoInitialize(nil);
try
InStream := TMemoryStream.Create;
try
InStream.LoadFromFile(FFileName);
OutStream := TMemoryStream.Create;
try
RetValue := DLLProcess(InStream, OutStream);
Sleep(0);
Debug('TDLLThread Result=> ' + IntToStr(RetValue));
if RetValue = 0 then
begin
Debug('TDLLThread OK');
end;
finally
OutStream.Free;
end;
finally
InStream.Free;
end;
finally
CoUninitialize;
end;
except
on E: Exception do
begin
Debug('TDLLThread Error: ' + E.Message);
end;
end;
end;
procedure TForm1.Button1Click(Sender: TObject); // Test
var
I: Integer;
begin
for I := 1 to 5 do
TDLLThread.Create(False, '1.xml');
end;
Run Code Online (Sandbox Code Playgroud)
在运行某些测试时,我有时会遇到Access Violations,即使是异常块也无法捕获.该程序只是与Runtime error 216 at xxxxxxx
或崩溃Invalid pointer operation
.
我已经尝试过静态和动态DLL链接(想象一下,动态链接可能在LoadLibrary/FreeLibrary中有竞争条件).
首先我认为IXMLDocument
是主要问题:
Doc := TXMLDocument.Create(nil);
Doc.LoadFromStream(InStream);
Run Code Online (Sandbox Code Playgroud)
这有时随机失败,没有明显的理由:
在文档的顶级无效.
要么:
名称以无效字符开头.
我想也许它使用了一些共享资源.但即使省略这些行也会导致AV!
所以DLL实际上没什么特别的.我也没有看到任何可以感染的特殊物品DLLMain
.
我不知道发生了什么......有人可以建议如何处理这种情况吗?(有人可以重现这种行为吗?)
编辑:我只是想添加一个相关的问题(与类似的IsMultiThread
解决方案):
Delphi DLL - 线程安全
以及一些提示IsMultiThread
:
IsMultiThread Variable
Delphi中的内存管理器对单线程使用进行了优化.这些是默认启用的.如果您的代码是多线程的,则需要禁用此优化.通过设置IsMultiThread
来做到这一点True
.
在创建一个Delphi线程模块,框架设置IsMultiThread
,以True
创建一个线程时.在你的程序的线程由主机创建的,所以没有在图书馆设置IsMultiThread
到True
.所以你必须在DLL中明确地这样做.在库.dpr文件的主要部分写这个:
begin
IsMultiThread := True;
end.
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
837 次 |
最近记录: |