关于动态链接库中的接口的问题,请指教(50分)

  • 主题发起人 主题发起人 happyfly051
  • 开始时间 开始时间
H

happyfly051

Unregistered / Unconfirmed
GUEST, unregistred user!
我在动态链接库中定义了一个接口,然后两个不同的应用程序都调用这个动态链接库,在动态库里要创建一个接口对象,请问,当两个程序运行时, 这个接口对象被创建几次啊?我本来的意思是它只能创建一个对象,这样写的
if not Assigned(_IDemoIntef) then
_IDemoIntef := TDemoIntf.Create;
result := _IDemoIntef;

可运行结果是两个程序都分别创建一个_IDemoIntef, 为什么啊?
 
贴更多代码出来看看.

要不参考我的一个应用 接口的 dll... demo 和 source 都有!

http://xease.net/read.php/37.htm
 
我看了你的demo了,为什么运行不了啊?出错提示为:无法定位程序输入点 CreatObj 于动态链接库LRC_INTERNET.dll上
 
我那个是两个应用程序都对同一个串口进行操作,为了避免两个程序同时对这个串口进行操作,想创建一个对象来对这个串口进行操作,因为这两个程序是用的一个dll,所有我在动态链接库里创建对象,源码如下
unit FInterface;

interface
Type
IDemoIntef = interface
function InitMsm(): Boolean; Stdcall;
function MySend(Port: Integer; Baud:Integer; SendStr: PChar; SendNum: PChar): Boolean; stdcall;
function Receive(Port: Integer; Baud: Integer; i: Integer; StrText: Pointer; StrNum: Pointer; StrTim: Pointer): Boolean; stdcall;
function ReInitMsm(Port: Integer; Baud: Integer): Boolean;
end;
implementation

end.

unit uInterClass;

interface

uses SysUtils, FInterface, syncObjs;


Type
TDemoIntf = Class(TInterfacedObject,IDemoIntef)
public
function InitMsm(): Boolean; Stdcall;
function MySend(Port: Integer; Baud:Integer; SendStr: PChar; SendNum: PChar): Boolean; stdcall;
function Receive(Port: Integer; Baud: Integer; i: Integer; StrText: Pointer; StrNum: Pointer; StrTim: Pointer): Boolean; stdcall;
function ReInitMsm(Port: Integer; Baud: Integer): Boolean;
end;

function CreateTDemointf: IDemoIntef; stdcall;
function GetHelloInit: IDemoIntef; stdcall;




implementation

function InitModem(comport:integer;baud:integer):boolean;stdcall; external 'Mysms.dll';
function SendSms(comport:integer; baud:integer; sMessage:Pointer; sSendto:Pointer; bEnglishSm:boolean; bAlertSm:boolean; bSR:boolean):boolean;stdcall; external 'Mysms.dll';
function SendAtCommand(comport:integer; baud:integer; sCmd:Pointer; sEcho:Pointer; nLen:integer):boolean;stdcall; external 'Mysms.dll';
function ReadSms(comport: integer; baud: integer; nIndex: integer; sMessage: Pointer; sFrom: Pointer; sTime: Pointer; bDel: boolean):boolean;stdcall; external 'Mysms.dll';


var
_IDemoIntef: IDemoIntef;
FLock: TCriticalSection;
InitFlag: Boolean;
function GetHelloInit: IDemoIntef; stdcall;
begin
try
if not Assigned(FLock) then
begin
FLock := TCriticalSection.Create;
end;

Result := CreateTDemointf;
except
end;
end;

function CreateTDemointf: IDemoIntef; stdcall;
begin
if not Assigned( _IDemoIntef) then
_IDemoIntef := Tdemointf.Create;


Result := _IDemoIntef;
end;

//***************初始化短信猫******************************
Function TDemoIntf.initmsm() : Boolean; StdCall;
begin
if ReInitMsm(1, 9600) then
begin
Result := True;
end else
begin
Result := False;
end;


end;

function TDemoIntf.ReInitMsm(Port: Integer; Baud: Integer): Boolean;
var
bb: Boolean;
ass: PChar; //at指令 at
ain: array [0..255] of Char; //返回的状态
begin
if not InitFlag then
begin
ass := 'at'#13;
FLock.Enter;
try
bb:=InitModem(Port, Baud);
finally
FLock.Leave;
end;

Sleep(200);

if bb then
begin
SendAtCommand(Port, Baud, ass, @ain[0], 255);

if (ain[2] = 'O') and (ain[3] = 'K') then
begin
Result := True;
InitFlag := True;
end else
begin
Result := False;
InitFlag := False;
end;
end else
begin
Result := False;
InitFlag := False;
end;
end else
begin
Result := True;
end;


end;
//**********发送短信******************************
function TDemoIntf.MySend(Port: Integer; Baud:Integer; SendStr: PChar; SendNum: PChar): Boolean; stdcall;
var
bb: Boolean;
i: Integer;
begin
i := 0;
repeat
FLock.Enter;
try
bb := SendSms(Port, Baud, SendStr, SendNum, False, False, False);
finally
FLock.Leave;
end;
Sleep(10);
i := i + 1;
until (not bb) and (i < 3);

if bb then
begin
Result := True;
end else
begin
InitMsm;
Result := False;
end;
end;

//**********读取短信******************************
function TDemoIntf.Receive(Port: Integer; Baud: Integer; i: Integer; StrText: Pointer; StrNum: Pointer; StrTim: Pointer): Boolean; stdcall;
var
bb: Boolean;
begin
bb := ReadSms(Port, Baud, i, StrText, StrNum, StrTim, True);
if bb then
begin
Result:=True
end else
begin
Result:=False;
end;
end;

initialization
InitFlag := False;

end.

library InterTest;

{ Important note about DLL memory management: ShareMem must be the
first unit in your library's USES clause AND your project's (select
Project-View Source) USES clause if your DLL exports any procedures or
functions that pass strings as parameters or function results. This
applies to all strings passed to and from your DLL--even those that
are nested in records and classes. ShareMem is the interface unit to
the BORLNDMM.DLL shared memory manager, which must be deployed along
with your DLL. To avoid using BORLNDMM.DLL, pass string information
using PChar or ShortString parameters. }

uses
ExceptionLog,
SysUtils,
Classes,
FInterface in 'FInterface.pas',
uInterClass in 'uInterClass.pas';

{$R *.res}

exports
GetHelloInit;
begin
end.

这就是我写的动态链接库的源码,麻烦老兄给看看吧
 
哪位大侠可以帮帮忙啊!
 
内存映象技术,该怎么解决
 
楼主,我修复 demo 了.你再看看.也不要因为一个错误就放弃了,那是我修改了一个 DLL 导出函数的名称,却来不及修改 header 文件就发布的错误,现在没事了... :)
 
好的,我回头看看,谢谢你
 
每个dll有自己的地址空间.两个dll的IDemoIntef互不相干.
使用内存映射文件 可以多个进程共用一块内存.
下面是创建一共用内存块方法.
pData 为一指针 可以为任何结构
hFileMapHandle := OpenFileMapping(FILE_MAP_WRITE, False, MappingFileName);
If (hFileMapHandle = 0) Then
hFileMapHandle := CreateFileMapping($FFFFFFFF, Nil, PAGE_READWRITE, 0, SizeOf(结构大小), MappingFileName);
pData := MapViewOfFile(hFileMapHandle, FILE_MAP_WRITE Or FILE_MAP_READ, 0, 0, 0);
 
to:总有爱
怎么对共享内存进行读写操作呢?
 
你需要数据的时候直接访问pData结构就可以了.
 
你看我是这样写的,不知道哪不对,反正运行不出我想要的结果
//定义一个记录类型
PData = ^RPtValue;
RPtValue = record
Pt_id:integer;
pt_value:string;
end;

//在第一个程序中创建共享内存并写入数据
procedure TForm1.btn1Click(Sender: TObject);
var
hFile:THandle;
hMapping:THandle;
data,d: PData;
i:integer;
pMap: Pointer;
begin
hMapping:=CreateFileMapping($FFFFFFFF,nil,PAGE_READWRITE ,0,1024,pchar('SHARE_MEMORY'));

if hMapping <> NULL then
begin
ShowMessage('创建成功');
end;

data := MapViewOfFile(hMapping,FILE_MAP_WRITE,0,0,0);

if data = nil then
begin
CloseHandle(HMapping);
ShowMessage('Can''t View Memory Map');
Application.Terminate;
end;
data.Pt_id := 0;
data.pt_value := mmo1.Text;
end;

//在第二个程序中读取共享内存中的数据
procedure TForm1.btn1Click(Sender: TObject);
var
hMap:THandle;
data,d: PData;
i:integer;
begin
hMap := CreateFileMapping($FFFFFFFF,nil,PAGE_READWRITE,0,1024,'SHARE_MEMORY');
if hMap = NULL then exit;

data := Mapviewoffile(hMap,FILE_MAP_READ,0,0,0);
d := data;
i := d.Pt_id;

mmo1.Lines.Add(d.pt_value);
end;

但是为什么读取不出来呢?
嘿嘿,大侠给看看吧
 
呵呵,那个问题知道怎么回事了,是该结贴的时候了,这个东西弄了好几天了,差点期末考试没考好,我是个菜鸟,所以分是出的多,进的少啊,呵呵,不过还是真心感谢你们
 
后退
顶部