在DLL中填写TStringList [英] Fill a TStringList in a DLL

查看:180
本文介绍了在DLL中填写TStringList的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想在DLL内填入一个 TStringList 。我的方法似乎对于内存管理文档是错误的,但它的作品并不会导致错误或AV。

I want to fill a TStringList inside a DLL. My approach seems to be wrong regarding memory management documentaion, but it works and doesn't cause an error or AV.

有人可以告诉我,如果该代码可以吗?不知道如何在DLL中填写一般的类。

Can someone tell me, if that code is OK? Not sure how I can fill a class in general in a DLL.

programm EXE

function MyClass_Create: IMyClass; stdcall; external ...

var
  _myClass_DLL: IMyClass; //shared interface in exe and dll

procedure FillList;
var
  list: TStringList;      
begin
  list := TStringList.Create(true); //memory allocated in EXE
  try
    _myClass_DLL.FillList(list);  //memory allocated in DLL???
    ShowMessage(list.Text);
  finally
    list.Free; //memory freed in EXE, frees also TObject created in DLL
  end;
end;

DLL代码:

library DLL

TMyClass = class(TInterfacedObject, IMyClass)
public
  procedure FillList(aList: TStringList);
end;

procedure TMyClass.FillList(aList: TStringList);
begin
  aList.AddObject('Text1', TObject.Create); //memory allocation in DLL?
  aList.AddObject('Text2', TObject.Create); //memory allocation in DLL?
end;

我不使用BORLNDMM.DLL或任何其他ShareMem单元。

I don't use BORLNDMM.DLL or any other ShareMem unit.

编辑:

我将 aList.Add()调用扩展到$ $ C> aList.AddObject()。它也不会崩溃,因为TObject在DLL中创建并在EXE中释放。


I expanded the aList.Add() call to aList.AddObject(). It also doesn't crash, altough the TObject is created in DLL and freed in EXE.

答案:

关于下面接受的答案中的意见,该代码是正确的,因为exe和dll是使用相同的delphi版本编译的,只有虚拟方法被调用。

Answer:
Regarding the comments in the accepted answer below, that code is correct, since exe and dll are compiled with the same delphi version and only virtual methodes are invoked.

结论:

只要使用虚拟方法或接口,内存管理没有问题。这意味着,创建对象或释放对象并不重要。

Conclusion:
As long as virtual methods or interfaces are used, there is no problem with memory management. That means, it doesn't matter where the object is created or freed.

推荐答案

如果要跨模块边界传递类那么您需要使用运行时包链接到RTL / VCL。这是确保您的DLL中的 TStringList 类与EXE中完全相同的唯一方法。这是您当前的方法的根本问题。另一方面,如果您已经使用运行时软件包链接到RTL,那么就可以了。

If you want to pass classes across module boundaries then you need to link to the RTL/VCL with runtime packages. That's the only way to make sure that the TStringList class in your DLL is the exact same one as in your EXE. That is the fundamental problem with your current approach. On the other hand, if you are already linking to the RTL with runtime packages, then you are fine.

如果您不想使用运行时包,则需要重新设计你的界面。您将需要停止在模块边界传递类。你可以使用接口,但不能使用类。并且您需要控制内存分配,以确保内存总是在分配给它的模块中释放。或者开始使用 ShareMem

If you don't want to use runtime packages then you need to redesign your interface completely. You would need to stop passing classes across the module boundary. You can use interfaces, but not classes. And you would need to take control of the memory allocation to ensure that memory is always deallocated in the module that allocated it. Or start using ShareMem.

这篇关于在DLL中填写TStringList的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆