DELPHI盒子
!实时搜索: 盒子论坛 | 注册用户 | 修改信息 | 退出
检举帖 | 全文检索 | 关闭广告 | 捐赠
技术论坛
 用户名
 密  码
自动登陆(30天有效)
忘了密码
≡技术区≡
DELPHI技术
lazarus/fpc/Free Pascal
移动应用开发
Web应用开发
数据库专区
报表专区
网络通讯
开源项目
论坛精华贴
≡发布区≡
发布代码
发布控件
文档资料
经典工具
≡事务区≡
网站意见
盒子之家
招聘应聘
信息交换
论坛信息
最新加入: hfh9801
今日帖子: 3
在线用户: 30
导航: 论坛 -> DELPHI技术 斑竹:liumazi,sephil  
作者:
男 hzjig868 (hzj) ★☆☆☆☆ -
盒子活跃会员
2003/12/17 20:18:26
标题:
一个从Dll中导出类的问题,为什么会出现这样的错误?谁能解答! 浏览:1735
加入我的收藏
楼主: 这是一个从Dll中导出类的例子,运行时会出现一个“EConvertError” 错误信息
是“cannot assign a TFont to a TFont", 如果不从Dll导出类,就没有这种错误。
该例子包含一个Dll工程,两个单元和一个调用Dll的程序。源码如下:

//-------  从Dll导出类发生错误的情况 -------------//

1。Dll工程

library DllObj;

{ 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
  SysUtils,
  Classes,
  dllclass in 'dllclass.pas';

{$R *.res}

exports
  NewObject;

begin
end.

----------------
2。base 单元

unit base;

interface

uses
  Controls, ComCtrls, ExtCtrls, Menus;

type
  TDllNumber = class
  public
    procedure InsertMenu(ParentMenu: TMainMenu); virtual; abstract;
    procedure InsertCtrl(APanel: TPanel); virtual; abstract;
  end;

implementation

end.

----------------
3。dllclass 单元

unit dllclass;

interface

uses
  windows, Menus, Controls, StdCtrls, ComCtrls, ExtCtrls, base;

type
  TDllNumberImpl = class(TDllNumber)
  private
    MenuItem: TMenuItem;
    FButton: TButton;
  Public
    constructor Create;
    destructor Destroy; override;
    procedure InsertMenu(ParentMenu: TMainMenu); override;
    procedure InsertCtrl(APanel: TPanel); override;
    procedure MenuItemOnClick(Sender: TObject);
  end;

  function NewObject: TDllNumber;


implementation

{ TDllNumberImpl }

constructor TDllNumberImpl.Create;
begin
  inherited Create;
end;

destructor TDllNumberImpl.Destroy;
begin
  if MenuItem <> nil then MenuItem.Free;
  if FButton <> nil then FButton.Free;
  inherited;
end;

procedure TDllNumberImpl.InsertCtrl(APanel: TPanel);
begin
  inherited;
  FButton := TButton.Create(APanel);
  FButton.parent := APanel;
  FButton.Caption := 'New Button';
  FButton.Left := 8;
  FButton.Top := 8;
end;

procedure TDllNumberImpl.InsertMenu(ParentMenu: TMainMenu);
begin
  MenuItem := TMenuItem.Create(ParentMenu);
  MenuItem.Caption := 'NewMenu';
  MenuItem.OnClick := MenuItemOnClick;
  ParentMenu.Items.Add(MenuItem);
  inherited;
end;

procedure TDllNumberImpl.MenuItemOnClick(Sender: TObject);
begin
  MessageBox(0, 'MenuItemClick test','Menu', mb_ok);
end;

function NewObject: TDllNumber;
begin
  Result := TDllNumberImpl.Create;
end;

end.

----------------
4。调用Dll的工程

unit CallDllObj;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, base, StdCtrls, Menus, ComCtrls, ExtCtrls;

type
  TForm1 = class(TForm)
    MainMenu1: TMainMenu;
    File1: TMenuItem;
    Panel1: TPanel;
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
  private
    { Private declarations }
    Num1: TDllNumber;
    procedure InitObject;

  public
    { Public declarations }
  end;
  
  function NewObject: TDllNumber; stdcall; external 'DllObj.dll'; 

var
  Form1: TForm1;

implementation


{$R *.dfm}

procedure TForm1.InitObject;
begin
    Num1 := NewObject;
    Num1.InsertMenu(MainMenu1);
    Num1.InsertCtrl(Panel1);
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  InitObject;
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
  Num1.Free;
end;


end.
----------------
//--------- 直接由调用类不出现错误的情况 ------------//

直接调用类时,在工程中直接引用 类所在的单元。

unit CallDllObj;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, base, StdCtrls, Menus, ComCtrls, ExtCtrls;

type
  TForm1 = class(TForm)
    MainMenu1: TMainMenu;
    File1: TMenuItem;
    Panel1: TPanel;
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
  private
    { Private declarations }
    Num1: TDllNumber;
    procedure InitObject;

  public
    { Public declarations }
  end;
  
//  function NewObject: TDllNumber; stdcall; external 'DllObj.dll'; 不从Dll中导入类

var
  Form1: TForm1;

implementation

uses
  dllclass; //直接引用类所在的单元

{$R *.dfm}

procedure TForm1.InitObject;
begin
  Num1 := NewObject;
  Num1.InsertTab(Panel1);
  Num1.InsertMenu(MainMenu1);
  Num1.InsertCtrl;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  InitObject;
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
  Num1.Free;
end;


end.
----------------------------------------------
-如果我说错了,相信我不是故意的。
作者:
男 sephil (NAILY Soft) ★☆☆☆☆ -
盒子中级会员
2003/12/18 20:33:15
1楼: { 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. }

在Dll的dpr和Exe的dpr添加 ShareMem单元
发布程序要带 DelphiMM.dll
----------------------------------------------
Copyright 2008 ? NAILY Soft

Click here to redirect to my home
Click here to redirect to my blog
信息
登陆以后才能回复
Copyright © 2CCC.Com 盒子论坛 v3.0.1 版权所有 页面执行89.84375毫秒 RSS