现在有一个这样的函数
function ReadIni(FileName,Section,Ident:string):string;stdcall;
是一个读文件的函数,返回的是字符串,上面的返回整型。
我用用样的方式调用它
.....
var
DLLHand:THandle;
ReadIni:TReadIni;
...
function FileName:string;
begin
Result:=ExtractFilePath(Application.ExeName) + 'MyConfig.INI';
end;function FileRead(FileName:string):string;
begin
try
DLLHand:=LoadLibrary('MyDLL.dll');
@ReadIni:=GetProcAddress(DLLHand,'ReadIni');
if @ReadIni <> nil then
Result := ReadIni(FileName,'BDConn','DBFileName');
finally
FreeLibrary(DLLHand);//这里已经出过N次异常了,自己写的。我是仿照书上写的,书上这里始终没有出过异常,我这仿它写一次就出了异常。
end;
end;异常提示:Exception:Debugger Fauilt Notification ....
access violation at Ox0000000 read of address Ox00000000,我点了帮助,进去后,它给我的注意是:
你的程序中可能存在一个努力继续导致错误再次产生的一个混乱不整洁的状态,你可能需要中止应用程序调查这个异常的原由
function ReadIni(FileName,Section,Ident:string):string;stdcall;
是一个读文件的函数,返回的是字符串,上面的返回整型。
我用用样的方式调用它
.....
var
DLLHand:THandle;
ReadIni:TReadIni;
...
function FileName:string;
begin
Result:=ExtractFilePath(Application.ExeName) + 'MyConfig.INI';
end;function FileRead(FileName:string):string;
begin
try
DLLHand:=LoadLibrary('MyDLL.dll');
@ReadIni:=GetProcAddress(DLLHand,'ReadIni');
if @ReadIni <> nil then
Result := ReadIni(FileName,'BDConn','DBFileName');
finally
FreeLibrary(DLLHand);//这里已经出过N次异常了,自己写的。我是仿照书上写的,书上这里始终没有出过异常,我这仿它写一次就出了异常。
end;
end;异常提示:Exception:Debugger Fauilt Notification ....
access violation at Ox0000000 read of address Ox00000000,我点了帮助,进去后,它给我的注意是:
你的程序中可能存在一个努力继续导致错误再次产生的一个混乱不整洁的状态,你可能需要中止应用程序调查这个异常的原由
我后来在uses那里加了一个ShareMem,这个在DLL的代码里也有,加上这个后就不会就那种异常了,但是新的异常又出现了。
在我FreeLibrary之后,没有出现错误,当我关闭这个应用程序后,就提示了一个EInvalidPointer的异常,我也不知道是什么原因导致的,然后我再继续运行就弹出一个错误
Runtime error at 217 at 00401276,好像在关闭应用程序后才弹出。
这个问题已经3个月没有解决了,现在解决了一半了,这些代码都是自己敲的,仿照书上敲的,书里有个光盘,那个上面的代码和我写的是一模一样,就是变量名称不一样,书上的代码怎么执行都没有异常的。
function FileRead(FileName:string):string;
type
IReadIni = function(FileName,Section,Ident:string):string;
var MyReadIni:IReadIni;
begin
try
DLLHand:=LoadLibrary('MyDLL.dll');
@MyReadIni:=GetProcAddress(DLLHand,'ReadIni');
if @ReadIni <> nil then
Result := MyReadIni(FileName,'BDConn','DBFileName');
finally
FreeLibrary(DLLHand);
end;
end;
另外,不要让DLL函数返回string类型,通常用PChar类型作输入输出参数。
还有,现在的问题是EInvalidPoint这个是string导致的吗?
为什么后来又有Runtime error 217 at 0041278
这个不是什么217-C不支持吗?我不是不想用PChar,是因为有一个函数ExtractFilePath()这个是返回string型的,这个函数是要在DLL的函数里调用,如果改城PChar就会说类型不一致,什么PChar和string的什么错误
ShareMem要放到dpr的第一个引用的单元,否则退出时会报错,因为内存管理器没有最先被替换。
你说的第一个单元是哪个单元?是系统的还是我自己写的?
ShareMem,我在每一个自己写的单元里都加了ShareMem,我在每一个自己写的单元里都加了ShareMem,我在每一个自己写的单元里都加了
如果这些还不对就要在所有系统的单元里加了!
ShareMem, //放到这
Forms,
Unit1 in 'Unit1.pas' {Form1};这才是dpr文件(项目文件)
library Mydll
uses Sharemem,...;
procedure xxxx...
exports
xxxxbegin
@dllproc:=....
end;
var
WIni :TIniFile;//定义一个对象
begin
WIni :=TIniFile.Create(string(FileName));//创建这个对象
try
WIni.WriteString(PString(Main),PString(Key),PString(Values));//开始写入文件
except
ShowMessage('文件写入错误!请检查文件位置是否正确。');
end;
WIni.Destroy;
end;
function ReadIni(FileName,Main,Key:PString):PString;
var
RIni :TIniFile;
begin
RIni :=TIniFile.Create(FileName);
try
Result :=PString(RIni.ReadString(PString(Main),PString(Key),PString('')));
except
ShowMessage('文件读取错误!请检查文件位置是否正确。');
end;
RIni.Destroy;
end;
procedure DeleteIni(FileName,Main,Key:PString);
var
DIni :TIniFile;
begin
DIni :=TIniFile.Create(FileName);
try
DIni.DeleteKey(PString(Main),PString(Key));
except
ShowMessage('删除文件错误!');
end;
DIni.Destroy;
end;
end.
你们自己看,我是不是没有进行强制转化之类的,我都转化了,但是编译不通过
[Error] Common.pas(20): Incompatible types: 'String' and 'PAnsiString'
这个错误有10多个,别说我没有基础什么的,我不是不知道转化,还有!你们说的那个PChar,这是什么?在字符,我要返回的是字符串,我想PChar返回的应该不多。就用的PString,这个类型D7应该认识了吧。我后来测试了PChar,一个数据库连接字符串到PChar那出来就剩10多个字符了,什么uid什么pwd都没有读到;
这里ReadString和WriteString这些函数里它本身就是要求是string类型的,函数体里面是对这些string参数用PChar转化的
procedure TIniFile.WriteString(const Section, Ident, Value: string);
begin
if not WritePrivateProfileString(PChar(Section), PChar(Ident),
PChar(Value), PChar(FFileName)) then
raise EIniFileException.CreateResFmt(@SIniFileWriteError, [FileName]);
end;
我在这里不用String用什么?这个函数是必须要用的。我一用PChar或者是PString就说两个类型不一致
function SQLDataSet(sqlText:string,ADOConn:TADOConnection):TDataSet;stdcall;extrnal 'SQLHandle.dll';
就像这样调用的函数,静态调用怎么出现了错误?
EAccessViolation,我不知道是为什么,我也在DLL里最前面添加了ShareMem了,应用程序中也添加过了ShareMem,不知道为什么会出错。