讨论几个Object Pascal的简单问题,有请基本功很扎实的朋友 (100分)

原来是试图主进程分配内存,然后dll中改变内存大小呀。
用 pointer应该不行,用string吧,然后uses sharemem,最后发布时连borlandmm.dll一起打包。你应当想到如果dll中动态改变主进程的内存块大小而没有副作用的话,borland也不会那么白痴去搞个sharemem了。
建议在调用dll的函数前将arr分配足够大的项数,调用后根据返回的具体个数调整这个arr。
 
试图主进程分配内存,然后dll中改变内存大小
思路应该是主进程调用函数,获得所需的内存大小,然后分配内存,再调用函数。
不过这种方式是API类型的,在实际应用当中,完全可以通过比如IStream(TStreamAdapter)/String+ShareMem等方法
预先分配足够大的空间是比较有局限性的
 
Another_eYes、zjan521:
思路应该是主进程调用函数,获得所需的内存大小,然后分配内存,再调用函数。
======================
这方法好,不过,在小弟的应用里面是行不通的。
因为在小弟的应用中,是要打开一个文件,一边分析文件内的数据,把需要的数据放进动态数组中。这样根本没有办法知道所需的内存是多大。也许你们会说先分配“打开的文件大小”的内存,这样也不行的。因为我可能文件内的数据都要,但我还要在数组中加进另外一些东西。

还有一种情况,就是如果从串口接收数据的话,你也不可能知道数据的大小的,也不能事先分配内存,只有动态的改。

所以,你们可不可以帮我想想,还有没有其他办法?
 
一个思路:
主程序多传一个var参数给dll,这个参数为一结构,它用于给dll记录数据分析中断点的信息。具体运行时分配一块内存作为结果(大小可能不够完全放入所有结果),初始化这个结构,然后一起作为参数传递给dll,dll进行操作,如果操作到一半发觉传入的内存不够大,则在结构中保存当前一些信息,通过特定返回值通知主程序调用失败,主程序接受到这个返回值后重新分配更大的内存继续调用,dll中则根据传入的结构找到上次的中断点继续执行。如此循环直到所有数据处理完成。
 
不过这种方式是API类型的,在实际应用当中,完全可以通过比如IStream(TStreamAdapter)/String+ShareMem等方法
 
还有高见吗?
 
如果用了开放数组 应在dll/appl 的dpr中均加入Uses Sharemem(必须是第一个引用单元)
因为在小弟的应用中,是要打开一个文件,一边分析文件内的数据,把需要的数据放进动态数组中。这样根本没有办法知道所需的内存是多大。也许你们会说先分配“打开的文件大小”的内存,这样也不行的。因为我可能文件内的数据都要,但我还要在数组中加进另外一些东西。

use 内存映射文件可以很好解决
 
只要第一个数组的数组元素的DataValue不是'AR'(即Array),就没有问题;所以,请大家主要想一想在Record的DataValue字段中,套一个动态数组时的情况(在DLL中)。

先静态声明两个动态数组 TSQDataArray PSQDataArray
dll 中不强制类型转换,拿来用可否

 
如果是我,我就会定义成:
uses ActiveX;

type
PVariantData = ^TVariantData;
TVariantData = TPropVariant;

PDataItem = ^TDataItem;
TDataItem = record
ID: Cardinal;
Data: TVariantData;
end;

然后看Variants.pas里面怎么操作变体类型的操作,哈,简单,而且保持其它语言的调用。

如果嫌麻烦,可以做成类型TPropVariant的结构体,用一个VType标识内容:字符,日期,整形。。。
System.varWord, varString已经有定义,用它做常量,呵,省的自己写。。。然后尽量不要用SetLength这种内部函数,直接用GetMem给一个数组分配好内存(如果想做成通用点的话)
 
用TVariantData对速度有影响的,大家怎么看呢?
 
多人接受答案了。
 

Similar threads

S
回复
0
查看
3K
SUNSTONE的Delphi笔记
S
S
回复
0
查看
2K
SUNSTONE的Delphi笔记
S
D
回复
0
查看
917
DelphiTeacher的专栏
D
顶部