当使用了长字符串类型的参数、变量时,如string,要引用ShareMem。

  虽然Delphi中的string功能很强大,但若是您编写的Dll文件要供其它编程语言调用时,最好使用PChar类型。如果您要坚持使用string类型的参数时、变量甚至是记录信息时,就要引用ShareMem单元,而且这个单元必须是第一个引用的,即在uses语句后的第一个单元。

  下面通过一个项目示例来讲解怎么使用ShareMem。

先新建一个DLL项目                 

  先新建一个DLL项目,然后再新建一个Unit1单元。

  工程文件是这样的

  1. library Project2;
  2.  
  3. { Important note about DLL memory management: ShareMem must be the
  4. first unit in your library's USES clause AND your project's (select
  5. Project-View Source) USES clause if your DLL exports any procedures or
  6. functions that pass strings as parameters or function results. This
  7. applies to all strings passed to and from your DLL--even those that
  8. are nested in records and classes. ShareMem is the interface unit to
  9. the BORLNDMM.DLL shared memory manager, which must be deployed along
  10. with your DLL. To avoid using BORLNDMM.DLL, pass string information
  11. using PChar or ShortString parameters. }
  12.  
  13. uses
  14. ShareMem,
  15. SysUtils,
  16. Classes,
  17. Unit1 in 'Unit1.pas';
  18.  
  19. {$R *.res}
  20. exports
  21. test;
  22.  
  23. begin
  24.  
  25. end.

  单元文件里面实现了test函数

  1. unit Unit1;
  2.  
  3. interface
  4. function test(const input: string): string; stdcall;
  5.  
  6. implementation
  7. function test(input: string): string; stdcall;
  8. begin
  9. Result:= '我是DLL中的test函数,输入是:' + input;
  10. end;
  11. end.

  引入ShareMem的注意事项

1. 因为DLL中使用到string类型,所以一定要引入ShareMem单元。如果没有用到string就不需要ShareMem,但是为了保险起见,还是建议引入ShareMem单元

2. 以这个项目为例,注意要在DLL的项目文件中引入ShareMem单元,而不是在函数的声明和实现单元Unit1里面引入ShareMem单元

3. 在项目文件中可能会引入很多单元,但是ShareMem单元一定要第一个引入,为了第一个加载

新建加载这个DLL的项目(生成可执行文件)     

  先新建一个项目,然后再新建一个Unit1单元。

  上面的那个DLL的项目编译生成了Project2.dll动态链接库,将该动态链接库文件放到这个可执行项目的项目目录下方便加载

  项目文件的源码是这样的

  1. program Project1;
  2.  
  3. uses
  4. ShareMem,
  5. Forms,
  6. Unit1 in 'Unit1.pas' {Form1};
  7.  
  8. {$R *.res}
  9.  
  10. begin
  11. Application.Initialize;
  12. Application.CreateForm(TForm1, Form1);
  13. Application.Run;
  14. end.

  单元文件的代码是这样的(这个单元文件中主要是窗体相关代码)

  1. unit Unit1;
  2.  
  3. interface
  4.  
  5. uses
  6. Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  7. Dialogs, StdCtrls;
  8.  
  9. type
  10. TForm1 = class(TForm)
  11. btn1: TButton;
  12. procedure btn1Click(Sender: TObject);
  13. private
  14. { Private declarations }
  15. public
  16. { Public declarations }
  17. end;
  18.  
  19. var
  20. Form1: TForm1;
  21.  
  22. implementation
  23.  
  24. {$R *.dfm}
  25.  
  26. procedure TForm1.btn1Click(Sender: TObject);
  27. type
  28. TAddc= function(const input: string): string; stdcall;
  29. var
  30. hh: THandle;
  31. addc: TAddc;
  32. begin
  33. hh:= LoadLibrary('Project2.dll');
  34. try
  35. if hh<>0 then
  36. @addc:= GetProcAddress(hh, PChar('test'));
  37. if not (@addc = nil) then
  38. begin
  39. ShowMessage(addc('lsls'));
  40. end;
  41. finally
  42. FreeLibrary(hh);
  43. end;
  44.  
  45. end;
  46.  
  47. end.

  这个可执行项目加载了上面的DLL,而上面的那个DLL里面使用到了string,所以这个项目文件中也需要引入ShareMem单元。

  但是也是有注意事项的:

1. 加载了使用string的DLL的项目也需要引入ShareMem。如果没有用到string就不需要ShareMem,但是为了保险起见,还是建议引入ShareMem单元

2. 以这个项目为例,注意要在该可执行项目文件中引入ShareMem单元,而不是在函数的声明和实现单元Unit1里面引入ShareMem单元

3. 在项目文件中可能会引入很多单元,但是ShareMem单元一定要第一个引入,为了第一个加载

  我在实验时候出现的问题

  因为我在可执行项目中引入ShareMem单元时候没有注意到应该在项目文件而不是在单元文件中引入,所以在编译执行之后,可以正确运行,但是当关闭程序的时候却报错,如下图

  报错:不合法的指针。

  将引入ShareMem单元的引入改到项目文件而不是在单元文件中,然后问题就解决了。

Delphi在创建和使用DLL的时候如果使用到string,请引入ShareMem单元的更多相关文章

  1. Delphi 动态与静态调用DLL(最好的资料)

    摘要:本文阐述了 Windows 环境下动态链接库的概念和特点,对静态调用和动态调用两种调用方式作出了比较,并给出了 Delphi 中应用动态链接库的实例. 一.动态链接库的概念    动态链接库(  ...

  2. Delphi插件创建、调试与使用应用程序扩展

    Delphi插件创建.调试与使用应用程序扩展 翻译 : MiracleZ  有没有使用过Adobe Photoshop?如果用过,你就会对插件的概念比较熟悉.对外行人来说,插件仅仅是从外部提供给应用程 ...

  3. 在VC中创建并调用DLL

    转自:http://express.ruanko.com/ruanko-express_45/technologyexchange6.html 一.DLL简介 1.什么是DLL? 动态链接库英文为DL ...

  4. Delphi窗体创建释放过程及单元文件小结(转)

    Delphi窗体创建释放过程及单元文件小结 Delphi中的窗体,有模式窗体与非模式窗体两种.两种窗体的调用方式不同,模式窗体使用ShowModal显示,非模式窗体使用Show显示.当显示模式窗体的时 ...

  5. 创建一个动态链接库 (DLL),使用VS2010

    在本演练中,您将创建一个动态链接库 (DLL),其中包含可供其他应用程序使用的有用例程.使用 DLL 是一种重用代码的绝佳方式.您不必在自己创建的每个程序中重新实现这些例程,而只需对这些例程编写一次, ...

  6. delphi编程创建桌面快捷方式

    delphi编程创建桌面快捷方式   uses ActiveX,ComObj,StdCtrls,ShlObj,FileCtrl; procedure TForm1.N2Click(Sender: TO ...

  7. 发现个delphi调用vc写的Dll中包括pchar參数报错奇怪现象

    发现个delphi调用vc写的Dll中包括pchar參数奇怪现象 procedure中的第一行语句不能直接调用DLL的函数,否则会执行报错,在之前随意加上条语句就不报错了奇怪! vc的DLL源代码地址 ...

  8. Delphi 调用C/C++的Dll(stdcall关键字, 会导致函数名分裂. 此时函数名变成_stdadd@8)

    delphi调用C++写的Dll, 当然这个Dll要求是非MFC的Dll, 这样子才能被delphi调用. 根据C++定义函数的情况, Delphi有不同的相对应的处理方法.1. 声明中不加__std ...

  9. 在Delphi中创建线程,请一定使用BeginThread()代替CreateThread()创建线程!(更好的管理异常)

    在Delphi中创建线程,请一定使用BeginThread()代替CreateThread()创建线程! 如果直接使用Win32的API函数CreateThread()创建多个线程,也是可以创建的.但 ...

随机推荐

  1. ios 快速审核

    https://developer.apple.com/contact/app-store/?topic=expedite

  2. express源码剖析1

    在通读源码之前,先把一些比较难理解的代码吃透: 1.EventEmitter.prototype mixin(app, EventEmitter.prototype, false); app为一个函数 ...

  3. Google数据交换格式:ProtoBuf

    Protocol Buffer ProtocolBuffer是Google公司的一个开源项目,用于结构化数据串行化的灵活.高效.自动的方法,有如XML,不过它更小.更快.也更简单.你可以定义自己的数据 ...

  4. css水平垂直居中对齐方式

    1.文字或者内联元素的垂直水平居中对齐 css属性 -- 水平居中:text-aligin:center; 垂直居中: line-height:height; 例子:. html: <div c ...

  5. mysql基于“报错”的注入

    报错是如何转为xss的? mysql语句在页面报错,泄露信息 ===================================================================== ...

  6. bind绑定参数

    const curry = (fn) => (...args)=>fn.bind(null,...args); const split = curry((splitOn, str) =&g ...

  7. (总结)隐藏PHP版本与PHP基本安全设置

    为了安全起见,最好还是将PHP版本隐藏,以避免一些因PHP版本漏洞而引起的攻击. 1.隐藏PHP版本就是隐藏 “X-Powered-By: PHP/5.2.13″ 这个信息. 方法很简单:编辑php. ...

  8. Ubuntu14.04 64位配置Caffe 教程(基于CUDA7.5)

    最新博客地址已转到: http://blog.csdn.net/zzlyw?viewmode=contents   ------------------------------------------ ...

  9. Socket网络编程二

    SocketServer socketserver一共有这么几种类型 class socketserver.TCPServer(server_address, RequestHandlerClass, ...

  10. C#夯实基础之多线程一:初识多线程

    一. 烧水沏茶问题       在小学四年级有一个烧水沏茶问题,可以作为我们今天讨论话题的引子: 客人来了,要烧一壶茶,但是烧水需要5分钟,洗水壶需要1分钟,洗茶杯需要2分钟,接水需要1分钟,找茶叶需 ...