用DELPHI开发DLL,如果其中包含有需要传递字符串的函数,那么怎么DLL就只能仅有着一个函数,如果添加其它函数,就会引起传递的字符串错误或内存冲突。我找了很多的资料,但都没有好的解决办法。难道delphi就只能开发这样的DLL吗?那位老大有这方面的经验,请不吝赐教!

解决方案 »

  1.   

    你用pchar传递,我的可以,任意多个函数没问题。
      

  2.   

    EXE跟DLL共享RTL,传什么都没有问题,包括String,就跟一个EXE中传参数一样
      

  3.   

    我的用pchar传递的结果也是一样,不能正常传递下去。
      

  4.   

    字符串使用PChar类型,不要使用String类型,这是delphi的内存管理问题,除非你使用BORLNDMM.DLL并且引用ShareMem,而且ShareMem必须是Library第一个引用的单元。推荐使用PChar做为字符串传递类型。
      

  5.   

    这是DLL的代码library dlltest;  { 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; 
      {$R *.res}  function  isRuning:integer;
      begin
        if threadcount>0 then
          result:=1
        else
          result:=0;
      end;  function  StartSend:integer;
      begin
        result:=1;
       readsetupfile;
    sendaction;
      end;function  SetThreadNum(i:integer):integer;
    begin
      threadnum:=i;
      result:=1;
    end;function  SetParameter(WPara:pchar;Lpara:pchar):integer;
    begin
      if Wpara='connstr' then
      begin
        Connstr:=lpara;
        result:=1;
      end;
     result:=0;end;exports
      startsend,
      isRuning,
      SetThreadNum,
      SetParaMeter;begin
    end.这是测试的unit frmmain;interfaceuses
      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}
    function  StartSend:boolean; stdcall; external 'dlltest.dll' name 'StartSend';
    function  isRuning:boolean; stdcall; external 'dlltest.dll' name 'isRuning';
    function  SetThreadNum(i:integer):boolean; stdcall; external 'dlltest.dll' name 'SetThreadNum';
    function  SetParameter(Wpara:pchar;Lpara:pchar):boolean; stdcall; external 'dlltest.dll' name 'SetParameter';procedure TForm1.btn1Click(Sender: TObject);
    var
      tf:boolean;
      value:string;
    begin tf:=isruning;
      if tf then
       showmessage('send....!')
      else
       showmessage('send finished');  tf:=SetThreadNum(20);
      if tf then
       showmessage('y')
      else
      showmessage('n'); tf:=SetParameter('connstr','teststr');
    if tf then
       showmessage('connstry')
      else
      showmessage('n');
    end;end.在测试运行时,在tf:=SetParameter('connstr','teststr');这一句时,系统就会报内存冲突。单步调试时,在DLL中读不到Wpara的值,到if Wpara='connstr' then 这一句时,就会报错。其它的函数可以正常传递并返回!
    如果去掉DLL中的其它几个函数后,字符串就可以正常传递参数下去了。并可以赋值给connstr
      

  6.   

    在delphi 7 和2006下都试验过,问题一样。因为编出来的DLL需要用其它的程序调用(vb或vc的),所以用静态调用方式调试。
      

  7.   

    你使用PAnsiChar试试吧...反正在DLL传递数据时用指针来传...还有函数区分大小数...
      

  8.   

    library dlltest;  { 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; 
      {$R *.res}  function  isRuning:integer;STDCALL;
      begin
        if threadcount>0 then
          result:=1
        else
          result:=0;
      end;  function  StartSend:integer;STDCALL;
      begin
        result:=1;
       readsetupfile;
    sendaction;
      end;function  SetThreadNum(i:integer):integer;STDCALL;
    begin
      threadnum:=i;
      result:=1;
    end;function  SetParameter(WPara:pchar;Lpara:pchar):integer;STDCALL;
    begin
      if Wpara='connstr' then
      begin
        Connstr:=lpara;
        result:=1;
      end;
     result:=0;end;exports
      startsend,
      isRuning,
      SetThreadNum,
      SetParaMeter;begin
    end.
      

  9.   

    写dll的时候,也是定义STDCALL;
      

  10.   

    解决!谢谢!原来用stdcall的时候用的是widestring,所以没效果。现在明白了