我有一个用 D2007 编译的 DLL,它具有返回 AnsiStrings 的函数。
我的应用程序是在 D2009 中编译的。当它调用 AnsiString 函数时,它会返回垃圾。
我创建了一个小测试app/dll来实验,发现如果app和dll都使用相同版本的Delphi(2007或2009)编译,则没有问题。但是当一个在 2009 年编译,另一个在 2007 年编译时,我得到了垃圾。
我尝试在这两个项目中包含最新版本的 FastMM,但即使这样,2009 年的应用程序也无法从 2007 年的 dll 中读取 AnsiStrings。
你知道这里出了什么问题吗?有办法解决这个问题吗?
最佳答案
AnsiStrings 的内部结构在 Delphi 2007 和 Delphi 2009 之间发生了变化。(不要沮丧;这种可能性从第一天起就存在。)Delphi 2009 字符串维护一个数字,指示其数据所在的代码页。
我建议您像地球上所有其他 DLL 所做的那样,传递函数可以填充的字符缓冲区。调用者应该传递一个缓冲区指针和一个指示缓冲区大小的数字。 (确保您清楚是以字节为单位还是以字符为单位测量大小。)DLL 函数填充缓冲区,写入的内容不超过给定的大小,并对终止空字符进行计数。
如果调用者不知道缓冲区应该有多少字节,那么您有两个选择:
当输入缓冲区指针为空时,使 DLL 表现出特殊的行为。在这种情况下,让它返回所需的大小,以便调用者可以分配那么多空间并再次调用该函数。
让 DLL 为自己分配空间,并使用预定的方法供调用者稍后释放缓冲区。 DLL 可以导出一个函数来释放它已分配的缓冲区,也可以指定一些相互可用的 API 函数供调用者使用,例如
GlobalFree
。您的 DLL 必须使用相应的分配 API,例如 GlobalAlloc。 (不要使用 Delphi 的内置内存分配函数,如GetMem
或New
;不能保证调用者的内存管理器知道如何调用Free
或Dispose
,即使它是用相同的语言编写的,即使它是使用相同的 Delphi 版本编写的。)
此外,编写只能由单一语言使用的DLL是自私的。以与 Windows API 相同的风格编写 DLL,这样就不会出错。
关于delphi - AnsiString 从 Delphi 2009 应用程序中的 Delphi 2007 DLL 返回值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1041421/