dll 中方法如下type
TmyArray=array of array of PChar;function getAllDepartmentDoctors1(departmentId: PChar): TmyArray; stdcall;
var
myarray1:TmyArray;
Query: TADOQuery;
count: Integer;
begin
CoInitialize(nil);
Query := TADOQuery.Create(nil);
try
try
Query.Close;
Query.ConnectionString := getConnectionString;
Query.SQL.Clear;
Query.SQL.Add('select userBasicInfo.FRK001_01 from TRK001 as userBasicInfo,'
+ ' TGY002 as doctor,TGY001 as department'
+ ' where userBasicInfo.FRK001_01= doctor.FRK001_01 and'
+ ' department.FGY001_01 = doctor.FGY001_01'
+ ' and department.FGY001_01=''320311000-01''');
Query.Open;
SetLength(myarray1, Query.RecordCount,Query.FieldCount);
count := 0;
Result := myarray1;
except
Query.Close;
Query.Free;
CoUninitialize;
ShowMessage('²Ù×÷Êý¾Ý¿âÒì³£:' + Exception(ExceptObject).Message);
end;
finally
Query.Close;
Query.Free;
CoUninitialize;
end;end;
调用的方法如下
type
TmyArray = array of array of PChar;function getAllDepartmentDoctors1(departmentId: PChar): TmyArray; stdcall;
external 'dll.dll';procedure TForm1.Button4Click(Sender: TObject);
var
HInst: THandle;
FPointer: TFarProc;
begin
try
HInst := LoadLibrary('dll.dll'); if HInst > 0 then begin
FPointer := GetProcAddress(HInst, 'getAllDepartmentDoctors1');
if FPointer <> nil then
begin
getAllDepartmentDoctors1(PChar('test'));
end
else
ShowMessage('error');
FreeLibrary(HInst);
end
else ShowMessage('dll not found');
except
ShowMessage('错误:' + Exception(ExceptObject).Message);
end;我点击按钮4 的时候去调用
前几次不会出错,大约到 第六次的时候就会有内存错误
我都纳闷死了,为什么前几次没有错误 非得连续调用了好几次会出现错误呢
TmyArray=array of array of PChar;function getAllDepartmentDoctors1(departmentId: PChar): TmyArray; stdcall;
var
myarray1:TmyArray;
Query: TADOQuery;
count: Integer;
begin
CoInitialize(nil);
Query := TADOQuery.Create(nil);
try
try
Query.Close;
Query.ConnectionString := getConnectionString;
Query.SQL.Clear;
Query.SQL.Add('select userBasicInfo.FRK001_01 from TRK001 as userBasicInfo,'
+ ' TGY002 as doctor,TGY001 as department'
+ ' where userBasicInfo.FRK001_01= doctor.FRK001_01 and'
+ ' department.FGY001_01 = doctor.FGY001_01'
+ ' and department.FGY001_01=''320311000-01''');
Query.Open;
SetLength(myarray1, Query.RecordCount,Query.FieldCount);
count := 0;
Result := myarray1;
except
Query.Close;
Query.Free;
CoUninitialize;
ShowMessage('²Ù×÷Êý¾Ý¿âÒì³£:' + Exception(ExceptObject).Message);
end;
finally
Query.Close;
Query.Free;
CoUninitialize;
end;end;
调用的方法如下
type
TmyArray = array of array of PChar;function getAllDepartmentDoctors1(departmentId: PChar): TmyArray; stdcall;
external 'dll.dll';procedure TForm1.Button4Click(Sender: TObject);
var
HInst: THandle;
FPointer: TFarProc;
begin
try
HInst := LoadLibrary('dll.dll'); if HInst > 0 then begin
FPointer := GetProcAddress(HInst, 'getAllDepartmentDoctors1');
if FPointer <> nil then
begin
getAllDepartmentDoctors1(PChar('test'));
end
else
ShowMessage('error');
FreeLibrary(HInst);
end
else ShowMessage('dll not found');
except
ShowMessage('错误:' + Exception(ExceptObject).Message);
end;我点击按钮4 的时候去调用
前几次不会出错,大约到 第六次的时候就会有内存错误
我都纳闷死了,为什么前几次没有错误 非得连续调用了好几次会出现错误呢
正常情况下,你应该是在exe中分配内存,并将内存传递到dll中,然后使用。
或者,你在DLL中分配内存,然后传给exe使用,然后在dll中释放内存。另外,你在 dll 中声明的 TmyArray 类型,和在exe 中声明的 TmyArray 类型,虽然形式上是一样的,但是他们是两种数据类型,呵呵,意外吧。你可以查看下他们的rtti信息。
下面是一个简单的测试证明他们是两种数据类型DLL中type
TmyArray = array of array of PChar;function abc(): Integer;
begin
Result := Integer(TypeInfo(TmyArray))
end;exports
abc;Exe中type
TmyArray = array of array of PChar;function abc(): Integer; stdcall; external 'Project2.dll';procedure TForm1.Button1Click(Sender: TObject);
begin
ShowMessage(Format(
'$%s (Exe中TmyArray的TypeInfo)'#13#10'$%s (dll中TmyArray的TypeInfo:)',
[IntToHex(Integer(TypeInfo(TmyArray)), 8),
IntToHex(Integer(abc()), 8)]));
end;
简单的例子如下exe中type
TMyArray = array of array of Integer;
PMyArray = ^TMyArray;
TExeFun = function (Mem: Pointer): Integer;function abc(pFun: TExeFun): Integer; stdcall; external 'Project2.dll';function exefun(mem: Pointer): Integer;
var
s: String;
i, j: Integer;
begin
s := '';
for i := 0 to 4 do
for j := 0 to 4 do
s := s + IntToStr(PMyArray(mem)^[i][j]) + ',';
ShowMessage(s);
Result := 0;
end;procedure TForm1.Button1Click(Sender: TObject);
begin
abc(exefun);
end;dll 中type
TMyArray = array of array of Integer;
PMyArray = ^TMyArray;
TExeFun = function (Mem: Pointer): Integer;function abc(pFun: TExeFun): Integer; stdcall;
var
MyArray1: TMyArray;
i, j: Integer;
begin
SetLength(MyArray1, 5, 5);
for I := 0 to 4 do
for j := 0 to 4 do
MyArray1[i][j] := (I + 1) * (j + 1);
pFun(Pointer(@MyArray1)); Result := 0;
end;exports
abc;上面的方式就可以实现谁分配谁释放的原则,呵呵。
另外,楼主声明的是PChar类型的数组,估计数组中还需要保存字符串指针,通过回调的方式,也不用考虑这些字符串指针的内存问题了。不过需要说明的是:不要再exe中释放传回数组以及数组中的字符串指针指向的字符串。建议使用bpl而不是dll来完成这些操作。在bpl中就可以避免数据类型不一致以及内存分配问题