Delphi在创建和使用DLL的时候如果使用到string,请引入ShareMem单元

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

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

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

先新建一个DLL项目                 

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

  工程文件是这样的

library Project2;

{ Important note about DLL memory management: ShareMem must be the
  first unit in your library‘s USES clause AND your project‘s (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. }

uses
  ShareMem,
  SysUtils,
  Classes,
  Unit1 in ‘Unit1.pas‘;

{$R *.res}
  exports
    test;

begin

end.

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

unit Unit1;

interface
  function test(const input: string): string; stdcall;

implementation
  function test(input: string): string; stdcall;
  begin
    Result:= ‘我是DLL中的test函数,输入是:‘ + input;
  end;
end.

  引入ShareMem的注意事项

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

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

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

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

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

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

  项目文件的源码是这样的

program Project1;

uses
  ShareMem,
  Forms,
  Unit1 in ‘Unit1.pas‘ {Form1};

{$R *.res}

begin
  Application.Initialize;
  Application.CreateForm(TForm1, Form1);
  Application.Run;
end.

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

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
  TForm1 = class(TForm)
    btn1: TButton;
    procedure btn1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.btn1Click(Sender: TObject);
type
  TAddc= function(const input: string): string; stdcall;
var
  hh: THandle;
  addc: TAddc;
begin
  hh:= LoadLibrary(‘Project2.dll‘);
  try
    if hh<>0 then
      @addc:= GetProcAddress(hh, PChar(‘test‘));
    if not (@addc = nil) then
    begin
      ShowMessage(addc(‘lsls‘));
    end;
  finally
    FreeLibrary(hh);
  end;

end;

end.

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

  但是也是有注意事项的:

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

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

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

  我在实验时候出现的问题

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

  报错:不合法的指针。

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

时间: 2024-10-10 04:55:28

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

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

Delphi插件创建.调试与使用应用程序扩展 翻译 : MiracleZ  有没有使用过Adobe Photoshop?如果用过,你就会对插件的概念比较熟悉.对外行人来说,插件仅仅是从外部提供给应用程序的代码块而已(举个例子来说,在一个DLL中).一个插件和一个普通DLL之间的差异在于插件具有扩展父应用程序功能的能力.例如,Photoshop本身并不具备进行大量的图像处理功能.插件的加入使其获得了产生诸如模糊.斑点,以及其他所有风格的奇怪效果,而其中任何一项功能都不是父应用程序自身所具有的.对于

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

在Delphi中创建线程,请一定使用BeginThread()代替CreateThread()创建线程! 如果直接使用Win32的API函数CreateThread()创建多个线程,也是可以创建的.但是,你应该明白,在每个线程中动态分配和销毁内存块,是需要同步保护的.Delphi语言中有一个在使用多线程环境下至关重要的全局变量IsMultiThread,系统在进行内存分配的时候,根据IsMultiThread变量值判断当前是否使用在多线程环境下,如果该变量为True,哪么,系统在分配和销毁内存的

Delphi代码创建形式规范 1.0

            Delphi代码创建形式规范 1.0 本规范的目的:给自己的代码一个统一而标准的外观,增强 可读性,可理解性,可维护性 本规范的原则:名称反映含义,形式反映结构 1.单元风格 2.各区风格 3.语句风格 4.命名规则 参考:Borland官方Object Pascal风格指南 Delphi5程序员指南编码标准 1.单元风格 {*******************************************************} { } { 项目名称 } { }

Delphi 调用C/C++的Dll(stdcall关键字, 会导致函数名分裂. 此时函数名变成[email&#160;protected])

delphi调用C++写的Dll, 当然这个Dll要求是非MFC的Dll, 这样子才能被delphi调用. 根据C++定义函数的情况, Delphi有不同的相对应的处理方法.1. 声明中不加__stdcall,采用VC默认格式__cdecl,但在Delphi中要注明调用格式为cdecl.C++中例子: [cpp] view plain copy print? extern "C" int __declspec(dllexport) add(int x, int y); Delphi中例

远程创建线程注入DLL

HANDLE WINAPI CreateRemoteThread(__in HANDLE hProcess,__in LPSECURITY_ATTRIBUTES lpThreadAttributes,__in SIZE_T dwStackSize,__in LPTHREAD_START_ROUTINE lpStartAddress,__in LPVOID lpParameter,__in DWORD dwCreationFlags,__out LPDWORD lpThreadId);hProce

发现个delphi调用vc写的Dll中包含pchar参数报错奇怪现象

发现个delphi调用vc写的Dll中包含pchar参数奇怪现象 procedure中的第一行语句不能直接调用DLL的函数,否则会运行错,在之前任意加上条语句就不报错了奇怪! vc的DLL源码地址 http://blog.csdn.net/lqena/article/details/46357165 Delphi源码如下: unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Co

在VS2010中创建并引用dll(C#)

一般情况下,如果在新建或添加时选择“windows应用程序”或“控制台应用程序”时,‎结果都会被编译成exe,而选择“类库”时就会被编译成dll.也可以在项目属性中更改其输出类型,如下图:         下面上一个创建dll并引用的实例.         1.新建一个项目,选择类库,命名DllTest.然后写一个类,里面包含一些方法什么的,为了突出主题,作为例子,我就写了一个简单的类,如下: using System; using System.Collections.Generic; usi

Delphi动态创建组件,并释放内存

开发所用delphi版本是xe2,效果图如下: 代码如下: ----------------------------------------------------------------------------------------------------------------- unit Unit1; interface uses Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Class

Visual Studio 创建和使用dll的方法

DLL是一个包含可由多个程序同时使用的代码和数据的库. DLL文件就是把一些函数导出来,然后在新程序中进行复用的过程. 第一部分:使用Visual Studio 2010进行DLL的制作 生成方法一: 第一步:选择创建win32应用程序 第二步:在弹出的应用程序向导中做出如下选择: 第三步:在头文件添加Demoone.h 代码如下: 1 #ifndef _Demo_H_ 2 #define _Demo_H_ 3 #ifdef LIBDLL 4 #define LIBDLL extern "C&q