请教:dll调用问题(100分)

  • 主题发起人 主题发起人 Dramer
  • 开始时间 开始时间
D

Dramer

Unregistered / Unconfirmed
GUEST, unregistred user!
我想学着自己做个dll,调用正常但是每次关闭时总是提示错误:access violation at 0x002331e2:read of address 0x00d42130'.
代码如下;
调用程序:
unit UntPurview;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, Menus, ComCtrls, ExtCtrls, Grids, DBGrids, DB, ADODB;

type
TForm1 = class(TForm)
Panel1: TPanel;
Panel2: TPanel;
Splitter1: TSplitter;
PageControl2: TPageControl;
TabSheet2: TTabSheet;
Splitter2: TSplitter;
PageControl1: TPageControl;
TabSheet1: TTabSheet;
Splitter3: TSplitter;
DBGrid1: TDBGrid;
TreeView1: TTreeView;
TreeView2: TTreeView;
TreeView3: TTreeView;
ADOQuery1: TADOQuery;
ADOC: TADOConnection;
DataSource1: TDataSource;
procedure FormCreate(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;

implementation

{$R *.dfm}
procedure Treeloading(Sender: TTreeView;ADOQ:TADOQuery;FirstNodestr,keyfeild,showfield:string); stdcall;

external 'TreeManage.dll';



procedure TForm1.FormCreate(Sender: TObject);
begin
Treeloading(TreeView3,ADOQuery1,'功能模块','deptid','deptname');
end;

end.
dll程序代码:
library TreeManage;

{ 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,ADODB,
ComCtrls;

{$R *.res}
function GetLevel(sFormat, sCode: String): Integer;
var
i,Level,iLen:Integer;
begin
Level:=-1;//如果代码不符合标准,则返回-1
iLen:=0;
if (sFormat <> '')and(sCode<> '')then
for i:=1 to Length(sFormat) do
begin
iLen:=iLen+StrToInt(sFormat);
if Length(sCode)=iLen then
begin
Level:=i;
Break;
end;
end;
Result:=Level;
end;
//
procedure Treeloading(Sender: TTreeView;ADOQ:TADOQuery;FirstNodestr,keyfeild,showfield:string); stdcall;
var
NowID,sName,ShowTxt:String;
i,Level:Integer;
MyNode:array[0..6]of TTreeNode; //保存各级节点,最长支持6级(重点)
const
SCodeFormat= '322222'; //科目代码结构
begin
//Screen.Cursor:=crHourGlass;//鼠标状态
//
ADOQ.DisableControls;// 关闭与数据表格相连接的控件来避免影响(界面效果与运行速度)
Sender.Items.BeginUpdate;
//
Level:=0;
With ADOQ do
begin
First;
Sender.Items.Clear;
//以下是增加第一项
MyNode[Level]:=Sender.Items.Add
(Sender.TopItem,FirstNodestr);
MyNode[Level].ImageIndex:=0;
MyNode[Level].SelectedIndex:=0;
//
While Not Eof do
begin
NowID:=Trim(FieldByName(keyfeild).AsString);
//ShowTxt:=NowID+''+FieldByName('aName').AsString; //显示当前编号
ShowTxt:=FieldByName(showfield).AsString;
Level:=GetLevel(SCodeFormat,NowID); //返回代码的级数
//以下用上一级节点为父节点添加子节点
if Level>0 then//确保代码符合标准
begin
MyNode[Level]:=Sender.Items.AddChild
(MyNode[Level-1],ShowTxt);
MyNode[Level].ImageIndex:=1;
MyNode[Level].SelectedIndex:=2;
end;
Next;
end;
end;
//
ADOQ.EnableControls;//恢复与数据表格相连接的控件(界面效果与运行速度)
Sender.Items.EndUpdate;
//
MyNode[0].Expand(False);//将首节点展开
//Screen.Cursor:=crDefault;//鼠标状态
end;
exports
Treeloading;
begin
end.
请有这方面经验的高手指点一下,谢谢
 
我就是想试着把一些常用的操作做成dll,但是没有这方面的经验。做了这个例子测试一下结果出错。希望有高手能给看一下。
 
应该是ADO未创建就调用了
 
把String类型改成Pchar类型
 
ADO是在调用窗体中创建的啊
 
没看到你代码里有loadlibrary、freelibrary呀,你怎么调用dll里的函数的?同时也没看到你在form中定义函数指针,建议采用规范的调用方法,可以避免莫名其妙的错误
 
你是想封装dll窗体吗?
 
我也遇到过这个问题,后来将String改成PChar就解决了。
 
呵呵 就是 动态链接库的接口函数在传递参数时不允许出现string类型,就是要将string改为pchar
 
谢谢了,我先测试一下
 
在Dll中包含Com时
需要初始化、释放...
 
具体用:
CoInitializ()
CoUnInitializ()
 
如果你要使用String类型的话,你可以在工程的第一个uses的单元为ShareMem,你在你的Dll中也要作类似的更改。
你也可以用FastMM来代替ShareMem,推荐你使用FastMM。
建议你用接口的方式来封装你的调用,然后把接口通过函数传递出去。
 

Similar threads

I
回复
0
查看
503
import
I
I
回复
0
查看
738
import
I
I
回复
0
查看
588
import
I
S
回复
0
查看
3K
SUNSTONE的Delphi笔记
S
S
回复
0
查看
2K
SUNSTONE的Delphi笔记
S
后退
顶部