使用了DLL出现access violation问题 |
答題得分者是:malanlk
|
baby2321
初階會員 發表:52 回覆:165 積分:48 註冊:2005-06-11 發送簡訊給我 |
DLL中的函数
function showdllform(Ahandle:Thandle;Acaption:string;tablename:string):string;stdcall;
var
newform:Tdllsec;
begin
application.Handle:=Ahandle;
newform:=Tdllsec.Create(application);
newform.Caption:=Acaption+'(选择)';
newform.ADOTable1.TableName:=tablename;
newform.ADOTable1.Active:=true;
try
newform.ShowModal;
result:=resultstr;
finally newform.Close;
end;
end; 另一个窗体:
//在输入时调用dll中的表格,选择名称和号码
procedure TInput.StringGrid1DblClick(Sender: TObject);
var
showForm:TShowDllForm;
module:Thandle; begin
if curCol<>1 then exit;
//读入dll
module:=loadlibrary('sec.dll');
if module<32 then exit;
@showForm:=getprocaddress(module,pchar(1));
if @showForm=nil then exit; //通过dll传递参数
stringgrid1.Cells[0,curRow]:=showForm(application.Handle,'选择名称','资料表'); //为代码添加名称
adoquery3.Close;
adoquery3.SQL.Clear;
adoquery3.SQL.Add('select 名称 from 资料表 where 代码=''' stringgrid1.Cells[0,curRow] '''');
adoquery3.Open;
stringgrid1.Cells[1,curRow]:=adoquery3.fieldbyname('名称').AsString;
stringgrid1.Cells[2,curRow]:='0';
stringgrid1.Cells[3,curRow]:='0'; end; 当通过DLL处理名称时 处理了几个后 出现
“Access violation at address 00402298 in module 'XXX.exe'.Write of address 01F1A888 ” 我想是不是使用了DLL的问题 有朋友说 将程序中使用完dll后 将其handle由free改为close 这样可以避免这种错误的发生
可是 我不知道 将其handle由free改为close 具体怎么写?
|
wameng
版主 發表:31 回覆:1336 積分:1188 註冊:2004-09-16 發送簡訊給我 |
|
baby2321
初階會員 發表:52 回覆:165 積分:48 註冊:2005-06-11 發送簡訊給我 |
|
baby2321
初階會員 發表:52 回覆:165 積分:48 註冊:2005-06-11 發送簡訊給我 |
|
wameng
版主 發表:31 回覆:1336 積分:1188 註冊:2004-09-16 發送簡訊給我 |
function showdllform(MainAPP:TApplication;Acaption:string;tablename:string):string;stdcall; var newform:Tdllsec; begin application :=MainAPP; .... end; var OldDllAPP : TApplication; procedure DllEnterPoint(Reason: Integer); begin Case Reason of DLL_PROCESS_ATTACH: begin OldDllAPP := Application; end; DLL_PROCESS_DETACH: begin Application := OldDllAPP; end; end; end; exports ShowDllForm; begin DLLProc := @DLLEnterPoint; DllEnterPoint(DLL_PROCESS_ATTACH); end.參考 ~~~~~~~~~~~ 難得聰明,常常糊塗。 ~~~~~~~~~~~ |
baby2321
初階會員 發表:52 回覆:165 積分:48 註冊:2005-06-11 發送簡訊給我 |
这里全部调整后代码
如下:
sec.dpr library sec;
uses
SysUtils,
Classes,
dllForm in 'dllForm.pas' {dllSec};
//此处是加入工程的unit,dllSec是该Unit的Name,而dllForm是该Unit保存的文件名
{$R *.res}
exports
showdllform index 1;
end. DLLForm调整为:
function showdllform(MainAPP:Tapplication;Acaption:string;tablename:string):string;stdcall;
var
newform:Tdllsec;
begin
application:=MainAPP;
newform:=Tdllsec.Create(application);
newform.Caption:=Acaption+'(双击选择)';
newform.ADOTable1.TableName:=tablename;
newform.ADOTable1.Active:=true;
try
newform.ShowModal;
result:=resultstr;
finally newform.Close;
end;
end; var
OldDllAPP : TApplication; procedure DllEnterPoint(Reason: Integer);
begin
Case Reason of
DLL_PROCESS_ATTACH:
begin
OldDllAPP := Application;
end;
DLL_PROCESS_DETACH:
begin
Application := OldDllAPP;
end;
end;
end; //-------双击选择数据栏---------
procedure TdllSec.DBGrid1DblClick(Sender: TObject);
begin
resultstr:=dbgrid1.Fields[0].Text;
close;
end; //--------设置表宽度----------
procedure TdllSec.FormShow(Sender: TObject);
var
i:integer;
begin
for i:=0 to dbgrid1.FieldCount-1 do
dbgrid1.Columns[i].Width:=64;
end; begin
DLLProc:= @DLLEnterPoint;
DllEnterPoint(DLL_PROCESS_ATTACH); end. F9之
提示:Cannot debug project unless a host application is defined.Use the Run|Parameters...dialog box.
即 此时产生一个新的DLL 在DELPHI中 运行主程序 其中一个窗体(代码已在上面贴出)在输入时调用dll中的表格,选择名称和号码
提示:Project xxx.exe raised exception class EAccess Violation with message 'Access violation at address 01DC5F20 in module 'sec.dll'.Read of address 000102E6.' PROESS stopped. 推出DELPHI 直接运行该EXE程序 在输入时调用dll中的表格 选择名称和号码
时
提示:Access Violation at address 01E55F20 in module 'sec.dll'.Read of address 000602DC. 此时不能实现 在输入时调用dll中的表格 选择名称和号码 没有调整前 可以 在输入时调用dll中的表格 选择名称和号码 只是 处理了几个或十几个或几十个后 出现
“Access violation at address 00402298 in module 'XXX.exe'.Write of address 01F1A888 ”
重新运行改EXE程序 可继续(即以前出现提示问题) 我估计是我现在没有改写正确 望wameng赐教
|
wameng
版主 發表:31 回覆:1336 積分:1188 註冊:2004-09-16 發送簡訊給我 |
我試一下,再也正常不過的事。
除了有點小問題外
function showdllform(MainAPP:Tapplication;Acaption:string;tablename:string):String;stdcall; var newform:Tdllsec; begin Application := MainAPP; newform := Tdllsec.Create(application); newform.Caption:=Acaption '(雙擊選擇)'; try newform.ShowModal; Result := newform.Edit1.Text;{用來測試的} finally FreeAndNil(newform);{不能用Close-> 不會釋放 NewForm} end; end;會不會是 ADOTable 出的問題。ADOConnection 設在哪? 一般是由 主程式提供。 先把 ADOTable 遮蔽試試。 ~~~~~~~~~~~ 難得聰明,常常糊塗。 ~~~~~~~~~~~ |
baby2321
初階會員 發表:52 回覆:165 積分:48 註冊:2005-06-11 發送簡訊給我 |
function showdllform(MainAPP:Tapplication;Acaption:string;tablename:string):String;stdcall;
var
newform:Tdllsec;
begin
Application := MainAPP;
newform := Tdllsec.Create(application);
newform.Caption:=Acaption '(双击选择)';
try
newform.ShowModal;
Result := newform.Edit1.Text;{用來測試的}
finally
FreeAndNil(newform);{不能用Close-> 不會釋放 NewForm}
end;
end; var
OldDllAPP : TApplication; procedure DllEnterPoint(Reason: Integer);
begin
Case Reason of
DLL_PROCESS_ATTACH:
begin
OldDllAPP := Application;
end;
DLL_PROCESS_DETACH:
begin
Application := OldDllAPP;
end;
end;
end;
begin
DLLProc:= @DLLEnterPoint;
DllEnterPoint(DLL_PROCESS_ATTACH); end. 生成DLL后
仍然提示:Project xxx.exe raised exception class EAccess Violation with message 'Access violation at address 01EE5F20 in module 'sec.dll'.Read of address 000C032E.' PROESS stopped. 只不过报错address 不同 我的ADOConnection连接的 是SQL SERVER2000中自己建立的数据库 我觉得数据库应该没有问题 如果是数据库的问题 那么我原来的情况下就应该有提示数据库连接或数据库出错的信息 ...头痛
|
baby2321
初階會員 發表:52 回覆:165 積分:48 註冊:2005-06-11 發送簡訊給我 |
|
wameng
版主 發表:31 回覆:1336 積分:1188 註冊:2004-09-16 發送簡訊給我 |
幾點建議: 1. 不要使用 String 因為這並非 Windows 標準,會造成不穩定! 建議改用 PChar。 如: function showdllform(MainAPP:Tapplication;Acaption:string;tablename:string):PChar;stdcall; var newform:Tdllsec; RltStr : String; begin Application := MainAPP; newform := Tdllsec.Create(application); newform.Caption := Acaption '(雙擊選擇)'; try newform.ShowModal; RltStr := newform.Edit1.Text; GetMem(Result,Length(RltStr)); Result := PChar(RltStr); finally FreeAndNil(newform);{不能用Close-> 不會釋放 NewForm} end; end; 2. 不要用字串當作回傳值,容易造成混淆。 誰去建立與釋放? 3. 最後提醒您! DLLProc:= @DLLEnterPoint; DllEnterPoint(DLL_PROCESS_ATTACH); 是放在 library sec 的 Begin ..End 中。 Good Luck ...~~~~~~~~~~~ 難得聰明,常常糊塗。 ~~~~~~~~~~~ 發表人 - wameng 於 2005/08/06 13:15:05 |
baby2321
初階會員 發表:52 回覆:165 積分:48 註冊:2005-06-11 發送簡訊給我 |
现在调整为
library sec;
uses
SysUtils,
Classes,
//此处是加入工程的unit,dllSec是该Unit的Name,而dllForm是该Unit保存的文件名
dllForm in 'dllForm.pas' {dllSec};
{$R *.res}
exports
//这是将要输出供外部调用的函数
showdllform index 1;
begin
DLLProc:= @DLLEnterPoint;
DllEnterPoint(DLL_PROCESS_ATTACH);
end.
------------------------------------------- unit dllForm;
{$R *.dfm}
function showdllform(MainAPP:Tapplication;Acaption:string;tablename:string):PChar;stdcall;
var
newform:Tdllsec;
RltStr : String;
begin
Application := MainAPP;
newform := Tdllsec.Create(application);
newform.Caption := Acaption '(雙擊選擇)';
try
newform.ShowModal;
RltStr := newform.Edit1.Text;
GetMem(Result,Length(RltStr));
Result := PChar(RltStr);
finally
FreeAndNil(newform);{不能用Close-> 不會釋放 NewForm}
end;
end; var
OldDllAPP : TApplication;
procedure DllEnterPoint(Reason: Integer);
begin
Case Reason of
DLL_PROCESS_ATTACH:
begin
OldDllAPP := Application;
end;
DLL_PROCESS_DETACH:
begin
Application := OldDllAPP;
end;
end;
end;
end.
---------------
F9之
提示: Symbol'INDEX' is specific to a platform
同时 DLLProc:= @DLLEnterPoint; 高亮显示 在此 多谢wameng悉心回复 我原来的目的只是希望实现双击窗体上stringgrid1.Cells可出现资料表数据 然后 双击资料表数据 将对应的资料表中的名称 返回到stringgrid1.Cells上 没想到搞的这么麻烦 不好意思啊 有个朋友说 就把
“DLL中的函数
function showdllform(Ahandle:Thandle;Acaption:string;tablename:string):string;stdcall;
var
newform:Tdllsec;
begin
application.Handle:=Ahandle;
newform:=Tdllsec.Create(application);
newform.Caption:=Acaption '(选择)';
newform.ADOTable1.TableName:=tablename;
newform.ADOTable1.Active:=true;
try
newform.ShowModal;
result:=resultstr;
finally newform.Close;
end;
end;”
中的 newform.Close;
改为 newform.free;. 我马上会数据测试看看
|
baby2321
初階會員 發表:52 回覆:165 積分:48 註冊:2005-06-11 發送簡訊給我 |
|
malanlk
尊榮會員 發表:20 回覆:694 積分:577 註冊:2004-04-19 發送簡訊給我 |
這個問題應該是和回答 jeffxx 的問題相同
http://delphi.ktop.com.tw/topic.php?TOPIC_ID=76298
|
wameng
版主 發表:31 回覆:1336 積分:1188 註冊:2004-09-16 發送簡訊給我 |
老實說,我覺得您的問題不在DLL form
在於 傳遞資料及指針上的問題。 建議改為
function showdllform(MainAPP:Tapplication;Acaption:string;tablename:string):PChar;
begin
....
Result := StrNew(PChar('要回傳內容.....')); 要不然將程序上傳。
或者 Email 至 cool.evon@msa.hinet.net。
我幫你看一看。因該問題不大! 唉!最近有點頭暈及有越來越迷糊的趨勢。
該不會是老了。.... ~~~~~~~~~~~
難得聰明,常常糊塗。
~~~~~~~~~~~
|
baby2321
初階會員 發表:52 回覆:165 積分:48 註冊:2005-06-11 發送簡訊給我 |
(我下面的描述可能会长一点) 这里 我总结一下代码和测试情况
首先 强调一下这些代码的目的:
是希望实现双击窗体上stringgrid1.Cells可出现资料表数据窗体 然后 双击资料表数据 将对应的资料表中的名称
返回到stringgrid1.Cells上 原来的所有源代码如下: -------------------
library sec;
uses
SysUtils,
Classes,
dllForm in 'dllForm.pas' {dllSec};
{$R *.res}
exports
showdllform index 1;
begin
end.
--------------------
unit dllForm;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, DB, Grids, DBGrids, ADODB;
type
TdllSec = class(TForm)
ADOTable1: TADOTable;
DBGrid1: TDBGrid;
DataSource1: TDataSource;
procedure DBGrid1DblClick(Sender: TObject);
procedure FormShow(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
function showdllform(Ahandle:Thandle;Acaption:string;tablename:string):string;stdcall;
var
resultstr:string;
implementation {$R *.dfm} function showdllform(Ahandle:Thandle;Acaption:string;tablename:string):string;stdcall;
var
newform:Tdllsec;
begin
application.Handle:=Ahandle;
newform:=Tdllsec.Create(application);
newform.Caption:=Acaption+'(双击选择)';
newform.ADOTable1.TableName:=tablename;
newform.ADOTable1.Active:=true;
try
newform.ShowModal;
result:=resultstr;
finally newform.Close;
end;
end;
//-------双击选择数据栏---------
procedure TdllSec.DBGrid1DblClick(Sender: TObject);
begin
resultstr:=dbgrid1.Fields[0].Text;
close;
end;
//--------设置表宽度----------
procedure TdllSec.FormShow(Sender: TObject);
var
i:integer;
begin
for i:=0 to dbgrid1.FieldCount-1 do
dbgrid1.Columns[i].Width:=64;
end; end.
---------------------以上生成DLL --------------------------
主程式下调用DLL的窗体设置的相应代码 unit unit1; interface uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, ComCtrls, ToolWin, ImgList, Grids, DBGrids, ExtCtrls, StdCtrls,
Buttons, DB, ADODB, DBCtrls, Mask;
......
procedure TInput.StringGrid1DblClick(Sender: TObject);
var
showForm:TShowDllForm;
module:Thandle; begin
if curCol<>1 then exit;
//读入dll
module:=loadlibrary('sec.dll');
if module<32 then exit;
@showForm:=getprocaddress(module,pchar(1));
if @showForm=nil then exit; //通过dll传递参数
stringgrid1.Cells[0,curRow]:=showForm(application.Handle,'选择名称','资料表'); //为代码添加名称
adoquery3.Close;
adoquery3.SQL.Clear;
adoquery3.SQL.Add('select 名称 from 资料表 where 代码=''' stringgrid1.Cells[0,curRow] '''');
adoquery3.Open;
stringgrid1.Cells[1,curRow]:=adoquery3.fieldbyname('名称').AsString;
stringgrid1.Cells[2,curRow]:='0';
stringgrid1.Cells[3,curRow]:='0'; end; ......
--------------------------
此阶段出现问题:当通过DLL处理名称时 处理了几个后 出现
“Access violation at address 00402298 in module 'XXX.exe'.Write of address 01F1A888 ”
关闭应用程序 再进入 可继续通过DLL处理名称 只是 又处理了几个后 仍出现如上错误提示信息 然后又得关闭应用程序 再进入 个人感觉可能是释放问题 TO: malanlk
你好 谢谢你的回帖 这个帖子后面有很多好的关于DLL方面应用的例子 很多都和我这个情况类似(可以说 在测试的这段过程中 他们出现的问题 我都出现过 而且错误提示信息基本相同) 刚才我花一点时间专门对这段代码(双击窗体上stringgrid1.Cells可出现资料
表数据 然后 双击资料表数据 将对应的资料表中的名称 返回到stringgrid1.Cells上)进行了测试 概括分为以下几种情况: 情况一:参照 http://delphi.ktop.com.tw/topic.php?TOPIC_ID=76298 中jeffxx 的类似解决方法:
在unit dllForm加入ShareMem 且把ShareMem放在最最前面
-------------------
library sec;
uses
SysUtils,
Classes,
dllForm in 'dllForm.pas' {dllSec};
{$R *.res}
exports
showdllform index 1;
begin
end.
--------------------
unit dllForm;
interface
uses
sharemem,Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, DB, Grids, DBGrids, ADODB;
type
TdllSec = class(TForm)
ADOTable1: TADOTable;
DBGrid1: TDBGrid;
DataSource1: TDataSource;
procedure DBGrid1DblClick(Sender: TObject);
procedure FormShow(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
function showdllform(Ahandle:Thandle;Acaption:string;tablename:string):string;stdcall;
var
resultstr:string;
implementation {$R *.dfm} function showdllform(Ahandle:Thandle;Acaption:string;tablename:string):string;stdcall;
var
newform:Tdllsec;
begin
application.Handle:=Ahandle;
newform:=Tdllsec.Create(application);
newform.Caption:=Acaption '(双击选择)';
newform.ADOTable1.TableName:=tablename;
newform.ADOTable1.Active:=true;
try
newform.ShowModal;
result:=resultstr;
finally newform.Close;
end;
end;
//-------双击选择数据栏---------
procedure TdllSec.DBGrid1DblClick(Sender: TObject);
begin
resultstr:=dbgrid1.Fields[0].Text;
close;
end;
//--------设置表宽度----------
procedure TdllSec.FormShow(Sender: TObject);
var
i:integer;
begin
for i:=0 to dbgrid1.FieldCount-1 do
dbgrid1.Columns[i].Width:=64;
end; end.
---------------------
F9之 提示产生新的DLL 再对主程式F9(此时主程式下的uses下 未加 sharemem) 调用dll中的表格,选择名称和号码 程序退出时 提示invalid pointer operation 錯誤訊息
有点类似http://delphi.ktop.com.tw/topic.php?TOPIC_ID=26599中degr 的一种情况下的错误 情况二:参考 jeffxx 他原来所借鉴的
http://delphi.ktop.com.tw/topic.php?topic_id=73693 中 reptile 的解答
“librarys.dpr 要加 uses sharememrep;
moneyshop.dpr(主程式) 也要加 uses sharememrep;
有用到 dll 的地方最好也加上 uses sharememrep;” 在uses最前面加上sharememrep 但我这里提示:File not Found :'sharememrep.dcu' 我又参考http://delphi.ktop.com.tw/topic.php?topic_id=73693 中 jumo的解答
“請檢查以下幾點
1. Libary 有無 Use ShareMem, 而且要放在第一個
2. 主程式 有無 Use ShareMem, 而且要放在第一個
3. reptile 所指點用的 ShareMemRep 這個 unit 我沒用過, 改試試看 ShareMem.” 于是 我把sharememrep改为sharemem加上去 我原来的代码就调整为(以下只写和原代码不同的部分 基本上是uses部分):
--------------------------
library sec;
uses
sharemem,
SysUtils,
Classes,
dllForm in 'dllForm.pas' {dllSec};
...
--------------------------//library sec所对应的unit dllForm的uses下未加sharemem
--------------------------
主程式下调用DLL的窗体设置的相应代码 unit unit1; interface uses
sharemem,Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, ComCtrls, ToolWin, ImgList, Grids, DBGrids, ExtCtrls, StdCtrls,
Buttons, DB, ADODB, DBCtrls, Mask;
......
--------------------------
程序在退出时 提示:invalid pointer operation 錯誤訊息 若是 在library sec ;其对应的unit dllForm;主程式下调用DLL unit unit1;的uses部分 都 在最前面加上sharemem
则 运行程序时 即 提示 invalid pointer operation 錯誤訊息 若是 只在library sec所对应的unit dllForm的uses下 加sharemem 即library sec;主程式下调用DLL unit unit1;都不加sharemem
则在程序调用DLL后
程序在退出时 提示 invalid pointer operation 錯誤訊息 若是 只在library sec下的uses 部分最前面加sharemem 即library sec所对应的unit dllForm的uses下; 主程式下调用DLL unit unit1;
都不加sharemem
则程序运行 调用DLL 退出 都无提示错误信息
只是在通过DLL处理名称时 处理了几个后 又出现
“Access violation at address 00402298 in module 'XXX.exe'.Write of address 01F1A888 ”即我现在代码中遇到的 问题 情况三:
http://delphi.ktop.com.tw/topic.php?TOPIC_ID=55744 中juneo 的"Invalid pointer operation"解决方式是
“作下列的修正,就可以傳回正確答案。
Result := PChar(IntToHex(J,2));”----------他的Result和我的Result效果作用我觉得一样 这是不是wameng刚才说的
“老實說,我覺得您的問題不在DLL form
在於 傳遞資料及指針上的問題。 建議改為
function showdllform(MainAPP:Tapplication;Acaption:string;tablename:string):PChar;
begin
....
Result := StrNew(PChar('要回傳內容.....'));”? 其实 我还是希望把unit dllForm中的
“newform.ADOTable1.TableName:=tablename;
newform.ADOTable1.Active:=true;”加进去修改 毕竟是希望通过双击数据库表中字段返回到主程式的tringgrid1.Cells上 谢谢 wameng malanlk 有你们真好
|
baby2321
初階會員 發表:52 回覆:165 積分:48 註冊:2005-06-11 發送簡訊給我 |
|
baby2321
初階會員 發表:52 回覆:165 積分:48 註冊:2005-06-11 發送簡訊給我 |
|
malanlk
尊榮會員 發表:20 回覆:694 積分:577 註冊:2004-04-19 發送簡訊給我 |
1. 建議用
http://delphi.ktop.com.tw/topic.php?topic_id=35228 的 sharememrep.pas 效能比較好 2. 建議您回應的程式碼用 [code]...〈程式碼〉...[/code]夾起來, 縮排就不會跑掉了. 3. ShareMemRep(ShareMem) 通常加一次就夠了加在.dpr的檔案內就可以了.
簡單的說明一下: 引發 "invalid pointer operation" 的原因是 DLL 和 EXE 使用了相同但各自獨立的記憶體管理機制, 所以在記憶體做回收合併時無法判斷記憶體區塊已經被釋放(由DLL建立,EXE釋放)而又做一次釋放的動作,所造成的. ShareMemRep 的作用就是希望EXE,DLL 用同一個記憶體管理機制. 之所以要加在最前面, 是因為 Compiler 會依照 uses 中列出的順序載入 Unit, 並執行 Initialization 及 Finalization 中的程式碼, 所以替換記憶體管理機制最好的時機就是加在 uses 最前面. .dpr 又是第一個被載入所以應該加在.dpr. 4. 經由上述說明 你第1個 invalid pointer... 是dll用了 ShareMem 機制, exe 還是用原來機制, 等於沒改. 第2,3個invalid pointer.. 是因為 ShareMem 沒加在主程式的 .dpr 檔案內, .dpr 檔案內的 uses 還是用原來的機制. 你在情況二最後又把 sec.dpr uses 中的 ShareMem 拿掉 當然就恢復原狀況了... 6. 結論是: 請在 主程式(xxx.dpr)及DLL(sec.dpr) 的 .dpr 檔案中的 uses 中加入 ShareMem 而且要在第一個....在提醒一次兩個都要加哦! 先這樣試試吧....
|
jeffxx
一般會員 發表:7 回覆:22 積分:5 註冊:2003-10-10 發送簡訊給我 |
function showdllform(MainAPP:Tapplication;Acaption:string;tablename:string):PChar; 說明上是說
if your DLL exports any procedures or functions that pass strings as parameters or function results
你要不要把引數(action、tablename)改成pchar試試
不然就先把string拿掉,值寫在dll中,把回傳值寫interger或其它的
先測功能有沒有 如果你要加sharemem
請加在最最前面
主程式加在
program Project1; <===加在這裡,不要加在其它unit裡面
uses
ShareMem,
Forms, dll內容 library Project1; <====加在這裡,不要加在其它unit裡面
uses
ShareMem,
SysUtils,
Classes,
Unit2 in 'Unit2.pas'; 以上是之前的測試
sorry 沒看清楚以上內就是malanlk大大上面的回覆 發表人 - jeffxx 於 2005/08/09 09:25:38 發表人 - jeffxx 於 2005/08/09 09:39:33 發表人 - jeffxx 於 2005/08/09 10:23:55
|
baby2321
初階會員 發表:52 回覆:165 積分:48 註冊:2005-06-11 發送簡訊給我 |
SORRY
昨天写的时候 把主程式下调用DLL的窗体 和 主程式搞混淆了
library sec; uses sharemem, SysUtils, Classes, dllForm in 'dllForm.pas' {dllSec}; ......主程式 unit MainForm; interface uses sharemem,Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, Menus, ComCtrls, DB, ADODB, StdCtrls; ......程序在退出时 还是提示:invalid pointer operation 錯誤訊息 |
malanlk
尊榮會員 發表:20 回覆:694 積分:577 註冊:2004-04-19 發送簡訊給我 |
|
baby2321
初階會員 發表:52 回覆:165 積分:48 註冊:2005-06-11 發送簡訊給我 |
真心感谢各位大大的 悉心指导 在下感激不尽
尤其是感谢 malanlk wameng jeffxx TO wameng:
阁下根本没老 你的回帖让我了解和学到了很多这方面的知识 积累了这方面的经验 再次谢谢你
LUCKY YOU
LUCKY ME
LUCKY US! 后注:
考虑到malanlk的建议
“1. 建議用http://delphi.ktop.com.tw/topic.php?topic_id=35228 的sharememrep.pas 效能比較好”
我在http://delphi.ktop.com.tw/topic.php?topic_id=35228下sharememrep 1.3和 sharememrep1.52 ShareMemRep解压到目标文件夹(主程式和DLL文件夹) 则此时在uses中可以
加入ShareMemRep而不会提示 file nor found'ShareMemRep.dcu' 当
program Project1;
uses
ShareMemrep,
Forms, dll內容 library Project1;
uses
ShareMemrep,
SysUtils,
Classes,
Unit2 in 'Unit2.pas'; 执行程序 调用DLL中 名称 时 sharememrep1.3下 提示:GOD,is a frightful calamity,Some library none load...You must Freelibrary()
for all dynamic library before process terminate! sharememrep1.52下 提示:
MemMgr Invalid!
-Have Loadlibrary(),but none Free library()!
-Have some memory leak! 于是我在 主程式下调用DLL的窗体设置的相应代码
unit unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, ComCtrls, ToolWin, ImgList, Grids, DBGrids, ExtCtrls, StdCtrls, Buttons, DB, ADODB, DBCtrls, Mask; ...... procedure TInput.StringGrid1DblClick(Sender: TObject); var showForm:TShowDllForm; module:Thandle; begin if curCol<>1 then exit; module:=loadlibrary('sec.dll'); if module<32 then exit; @showForm:=getprocaddress(module,pchar(1)); if @showForm=nil then exit; stringgrid1.Cells[0,curRow]:=showForm(application.Handle,'选择名称','资料表'); freelibrary(module);// 加入freelibrary adoquery3.Close; adoquery3.SQL.Clear; adoquery3.SQL.Add('select 名称 from 资料表 where 代码=''' stringgrid1.Cells[0,curRow] ''''); adoquery3.Open; stringgrid1.Cells[1,curRow]:=adoquery3.fieldbyname('名称').AsString; stringgrid1.Cells[2,curRow]:='0'; stringgrid1.Cells[3,curRow]:='0'; end; ......执行程序 在通过DLL处理名称时 提示我在调用DLL的窗体中 另一过程的一个变量设置有问题 http://delphi.ktop.com.tw/topic.php?topic_id=35228中 Aimingoo 提到“使用ShareMemRep,可以徹底地拋開BORLNDMM.DLL和ShareMem.pas單元。 你無需再關心ShareMem的細節,因為DLL與EXE使用了同一個內存管理器。由此帶來的另一個好處是: 你可以隨意替換EXE中的內存管理器,而無需更改DLL中的任何代碼” 以后程序发布 是不是要把BORLNDMM.DLL一起发布?那样岂不是有些麻烦 |
malanlk
尊榮會員 發表:20 回覆:694 積分:577 註冊:2004-04-19 發送簡訊給我 |
1."徹底地拋開BORLNDMM.DLL...." 就是不用再發佈... 2. http://delphi.about.com/od/objectpascalide/l/aa103003b.htm 中的 FastSharemem unit http://delphi.about.com/gi/dynamic/offsite.htm?site=http://www.codexterity.com/fastsharemem.htm 也可以試試...速度據說都有 4-8 倍以上
|
baby2321
初階會員 發表:52 回覆:165 積分:48 註冊:2005-06-11 發送簡訊給我 |
|
baby2321
初階會員 發表:52 回覆:165 積分:48 註冊:2005-06-11 發送簡訊給我 |
|
malanlk
尊榮會員 發表:20 回覆:694 積分:577 註冊:2004-04-19 發送簡訊給我 |
|
baby2321
初階會員 發表:52 回覆:165 積分:48 註冊:2005-06-11 發送簡訊給我 |
本站聲明 |
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。 2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。 3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇! |