dLL创建与sharemem.doc
文本预览下载声明
如果你的DLL导出函数中,有类型string的参数,那么要加sharemem,并且在发布程序的时候,要有borlndmm.dll(搜索的时候注意大小写)
一般在C:\Program Files\Borland\Delphi7\Bin
如果一个uses子句中需要出现ShareMem单元,那么该单元总是列于首位。
写了一个?DLL ,封装了一个类,该类有一个函数名为 WriteRecord(P: Pointer),其中参数 P 是一个记录指针,子类在 override 该函数时学根据将 P 指针转为子类所支持的记录类型,如:
var
??? pt: PBookInfo;
begin
?? pt := PBookInfo(P);
?? ...
end;
该 DLL 有一个导出函数:
? function CreateObj: TObjType; stdcall;
这个 DLL 采用动态加载的办法:
DllHandle := LoadLibrary(abc.dll);
加载成功后调用CreateObj函数创建了一个对象,然后调用了该对象的 WriteRecord 函数,此过程一切正常,然而,完毕之后调用FreeLibrary(DllHandle)时出错,经过排查发现是调用了 WriteRecord 函数导致的,在网上查了资料,并认真看了 DLL 的 dpr 文件开头部分的注释:
Important note about DLL memory management: ShareMem must be the? first unit in your librarys USES clause AND your projects (select? Project-View Source) USES clause if your DLL exports any procedures or? functions that pass strings as parameters or function results. This? applies to all strings passed to and from your DLL--even those that? are nested in records and classes. ShareMem is the interface unit to? the BORLNDMM.DLL shared memory manager, which must be deployed along? with your DLL. To avoid using BORLNDMM.DLL, pass string information? using PChar or ShortString parameters.
这段文字的意思是:如果你的 DLL 导出了含有 string 类型的参数或者返回值为 string 类型,则必须将 ShareMem 作为 DLL 和 代用 DLL 的工程的第一个引用单元,这对于所有的含有 string 类型传递的情况都有效,即使是 string 类型嵌套在记录或者类中。【英语不好,翻译可能不准确,但意思应该是清楚的】
于是,在 DLL 和 调用 DLL 的工程 的dpr 文件中都引用的ShareMem,就没有出问题了。
以下是网上找到关于ShareMem 的说明,仅供参考:
-------------------------------------------------------------------------------------------------
1) ShareMem单元说白了就是替换EXE和DLL各自的内存管理器,使它们共同使用一个内存管理器,所以它需要在DLL和EXE中同时加入,执行的时候,总是先执行EXE文件,这时候ShareMem中的内存管理器替换EXE原来的内存管理器,当DLL被加载的时候,ShareMem单元再次被调用,它检查是否已经有了ShareMem单元的管理器,如果有了,就直接使用它。这样就完成了共用一个内存管理器的工作。如果只在DLL中使用ShareMem单元而忘了在EXE中也把它加上,ShareMem单元其实是没有意义的。
2) Borland 的 ShareMem 单元应该放入 EXE 和 DLL 才有作用,但是当把它仅仅放入 EXE 而不放入 DLL 的话,等于这个 ShareMem 中的内存管理器无效,如果仅仅放入 DLL 而不放入 EXE 的,退出 DLL 时就会如上面例子那样报运行时错误。 实际上,从 Delphi6 开始,常数String参数的传递已经不需要 ShareMem 这个单元了,也就是说,上
显示全部