子模块采用DLL方式调用,其中带入DLL中的有TAdodsOp和TGlobal公共变量参数,(AHandle: THandle; AdoServer: TAdoDsOp; AGlobal: TGlobal)--详细参数情况
TAdodsOp和TGlobal带入后采用内存映射方式进行调用。现问题是:
1、若两个系统同时调用这个DLL时,会报地址冲突错误,经跟踪,是刷新数据集时报错。
2、单个系统在调用DLL或退出时,也会偶儿报一些地址错错误。请大虾帮忙看下,这问题该如何解决?
以下是内存映射使用方式:
unit uMemMap;interfaceuses windows, sysutils, uadoDsOp, uGlobal, Forms, ActiveX;const
VirtualFile1 = 'HS_ADOSERVER_SHAREDLL';
VirtualFile2 = 'HS_GLOBAL_SHAREDLL';
DataSize1 = sizeof(TAdoDsOp);
DataSize2 = sizeof(TGlobal);var
hMapFile1: THandle;
hMapFile2: THandle; //------------------------------------------
_AdoServer: ^TAdoDsOP; //必须使用内存映射文件
_Global: ^TGlobal;
_OldHandle: THandle;
implementationinitialization CoInitialize(nil);
//使用内存映射文件来共享接口
//创建AdoServer接口的内存映射文件
hMapFile1 := CreateFileMapping($FFFFFFFF, nil,Page_ReadWrite, 0, DataSize1, VirtualFile1);
if hMapFile1 = 0 then
begin
raise Exception.Create ('创建IAdoDsOP内存映射文件错误!');
Application.Terminate;
end;
_AdoServer := MapViewOfFile (hMapFile1, File_Map_Write, 0, 0, DataSize1); //创建Global类的内存映射文件
hMapFile2 := CreateFileMapping($FFFFFFFF, nil,Page_ReadWrite, 0, DataSize2, VirtualFile2);
if hMapFile2 = 0 then
begin
raise Exception.Create ('创建Global类内存映射文件错误!');
Application.Terminate;
end;
_Global := MapViewOfFile (hMapFile2, File_Map_Write, 0, 0, DataSize2);finalization
UnmapViewOfFile(_AdoServer);
UnMapViewOfFile(_Global);
CloseHandle(hMapFile1);
CloseHandle(hMapFile2);
CoUninitialize;
end.以下是带入参数使用方式:
procedure ShowCard(AHandle: THandle; AdoServer: TAdoDsOp; AGlobal: TGlobal; ACardNo, AMonth: PChar; ADataType: integer); stdcall;
var
AOldHandle: THandle;
begin _AdoServer^ := AdoServer;
_Global^ := AGlobal;
AOldHandle := Application.Handle;
application.Handle := AOldHandle;
end;
TAdodsOp和TGlobal带入后采用内存映射方式进行调用。现问题是:
1、若两个系统同时调用这个DLL时,会报地址冲突错误,经跟踪,是刷新数据集时报错。
2、单个系统在调用DLL或退出时,也会偶儿报一些地址错错误。请大虾帮忙看下,这问题该如何解决?
以下是内存映射使用方式:
unit uMemMap;interfaceuses windows, sysutils, uadoDsOp, uGlobal, Forms, ActiveX;const
VirtualFile1 = 'HS_ADOSERVER_SHAREDLL';
VirtualFile2 = 'HS_GLOBAL_SHAREDLL';
DataSize1 = sizeof(TAdoDsOp);
DataSize2 = sizeof(TGlobal);var
hMapFile1: THandle;
hMapFile2: THandle; //------------------------------------------
_AdoServer: ^TAdoDsOP; //必须使用内存映射文件
_Global: ^TGlobal;
_OldHandle: THandle;
implementationinitialization CoInitialize(nil);
//使用内存映射文件来共享接口
//创建AdoServer接口的内存映射文件
hMapFile1 := CreateFileMapping($FFFFFFFF, nil,Page_ReadWrite, 0, DataSize1, VirtualFile1);
if hMapFile1 = 0 then
begin
raise Exception.Create ('创建IAdoDsOP内存映射文件错误!');
Application.Terminate;
end;
_AdoServer := MapViewOfFile (hMapFile1, File_Map_Write, 0, 0, DataSize1); //创建Global类的内存映射文件
hMapFile2 := CreateFileMapping($FFFFFFFF, nil,Page_ReadWrite, 0, DataSize2, VirtualFile2);
if hMapFile2 = 0 then
begin
raise Exception.Create ('创建Global类内存映射文件错误!');
Application.Terminate;
end;
_Global := MapViewOfFile (hMapFile2, File_Map_Write, 0, 0, DataSize2);finalization
UnmapViewOfFile(_AdoServer);
UnMapViewOfFile(_Global);
CloseHandle(hMapFile1);
CloseHandle(hMapFile2);
CoUninitialize;
end.以下是带入参数使用方式:
procedure ShowCard(AHandle: THandle; AdoServer: TAdoDsOp; AGlobal: TGlobal; ACardNo, AMonth: PChar; ADataType: integer); stdcall;
var
AOldHandle: THandle;
begin _AdoServer^ := AdoServer;
_Global^ := AGlobal;
AOldHandle := Application.Handle;
application.Handle := AOldHandle;
end;
Access violation at address 0391C110. Read of address 039C110.
Access violation at Address 06FEC110. Read of address 06FEC11.
Access violation at address 0413E4A5 in module 'name.dll'. Read at address 03E9582C.
Access violation at address 0398E4A5 in module 'name.dll'. Read of address 03E2582C.
hMapFile1 := CreateFileMapping($FFFFFFFF, nil,PAGE_WRITECOPY, 0, DataSize1, VirtualFile1);
if hMapFile1 = 0 then
begin
raise Exception.Create ('创建IAdoDsOP内存映射文件错误!');
Application.Terminate;
end;
_AdoServer := MapViewOfFile (hMapFile1, FILE_MAP_COPY, 0, 0, DataSize1);现另一个DLL偶儿会报地址错的问题,不知会不会因这错误的解决而解决,有待考证。
2 无论如何,你都不能够使用FileMapping来共享接口,因为不同进程的地址空间都是独立的,是不能共享的,除非你只共享数据.
3 如果不是特别必要,不要随意修改Application
4 你确实要共享接口,你可以使用com,用一个automation的exe服务器来创建接口.
能否说明清楚一些?或是解决办法?
准备结贴了。
谢谢muroachanf的回复