我写了个Dll,为了看Delphi写的DLL是否稳定,我是循环来测试,连续执行1000次,结果不到50次就会报错,然后我在调用Dll的单元中加上 ShareMem 单元,结果非常稳定,但是我关闭程序的时候就会报错!!!不知道为什么?后来我新建一个应用程序,在一个空白的窗体单元加上 ShareMem 单元,
然后我啥也不干,运行程序,结果退出时报错!!!服了,难道 ShareMem 单元不能用?不信的话你可以新建一个应用程序,然后在unit1的首位置加上 ShareMem 单元,然后运行程序,关闭,看报错不?我用的D7就是报错!!!

解决方案 »

  1.   

    好象跟Dll没关系,主要是加上ShareMem后,退出时就报错!!!我是想知道这个单元到底能不能用?
      

  2.   

    delphi有自己的string管理机制,默认的application不需要加。
    但是在dll与application之间,很有可能你application里的一个string内存在dll中被释放了,那么再到application去的时候,就会报错。
    所以必须加sharemem协调string管理机制!On Windows, if a DLL exports routines that pass long strings or dynamic arrays as parameters or function results (whether directly or nested in records or objects), then the DLL and its client applications (or DLLs) must all use the ShareMem unit. The same is true if one application or DLL allocates memory with New or GetMem which is deallocated by a call to 
    Dispose or FreeMem in another module. ShareMem should always be the first unit listed in any program or library uses clause where it occurs.ShareMem is the interface unit for the BORLANDMM.DLL memory manager, which allows modules to share dynamically allocated memory. BORLANDMM.DLL must be deployed with applications and DLLs that use ShareMem. When an application or DLL uses ShareMem, its memory manager is replaced by the memory manager in BORLANDMM.DLL.
      

  3.   

    你的情况是正常的,一般的应用程序不需要添加sharemem。
      

  4.   

    晕,竟然还要带上BorlandMM.dll,不想带这个MM怎么办?
      

  5.   

    sharemem 是 dll 中用的, 反正我是没在 application 中用过, 在 dll 中用到了 string 这种东东或者是 delphi 带的任何一个分配释放内存程序时, 就得用上, 放在 exe 里没试过呵, 估计是有点问题的吧, shremem 代替了application 的分配释放的函数, 是一些对像, 主程序退出时先会去释放 sharemem, 但主程序之后也要释放对像, sharemem 都没了, 释放对像的函数就不存在了吧,,,,大概这样, 有点想当然的感觉呵
      

  6.   

    ShareMem is the interface unit for the BORLANDMM.DLL memory manager, which allows modules to share dynamically allocated memory. BORLANDMM.DLL must be deployed with applications and DLLs that use ShareMem. When an application or DLL uses ShareMem, its memory manager is replaced by the memory manager in BORLANDMM.DLL.上面的意思是不是有一个 BORLANDMM.DLL 要和使用 ShareMem 和程序或者DLL,一起配置?
    但我搜遍整个电脑,就是找不到那个DLL,是不是帮助文档年代太久了,没更新!!
      

  7.   

    o, 那个叫 borlndmm.dll 为了8.3格式少个a哈, 用了 sharemem 就必须同时发行 borlndmm.dll
    注意没有什么静态 link 一说, 必须同时
      

  8.   

    如果你的DLL导出函数中,有类型string的参数,那么要加sharemem,并且在发布程序的时候,要有borlndmm.dll(搜索的时候注意大小写)
    一般在C:\Program Files\Borland\Delphi7\Bin
      

  9.   

    library Project1;{ 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
      SysUtils,
      adodb,
      Windows,
      Classes;var
        Qry : TADOQuery;{$R *.res}procedure InitDll(ConStr:Pchar);stdcall;
    begin
        Qry := TADOQuery.Create(nil);
        Qry.ConnectionString := ConStr;
    end;function QueryDll(TableName,ID:pchar):Pchar;stdcall;
    var
        i: integer;
        s: String;
        h: HWND;
    begin
        s := '';
        Result := Pchar(s);
        h := GetForeGroundWindow();
    //    MessageBox(h,PChar(Qry.ConnectionString),'dll',MB_OK or MB_ICONINFORMATION);
        try
            with Qry do
            begin
                CLose;
                SQL.Text := Format('select * from %s where id = %s ',[TableName,ID]);
                Open;
            end;
            if Qry.IsEmpty then
            begin
                Exit;
            end;
            for i := 0 to Qry.FieldCount - 1 do
            begin
                if i = 0 then
                    s := Qry.Fields[0].AsString
                else
                    s := s + '#'+ Qry.Fields[i].AsString;
            end;
        except
        end;
        Result := Pchar(s);
    end;procedure CloseDll() ;stdcall;
    var
        h: HWND;
    begin
        h := GetForeGroundWindow();
        MessageBox(h,'CloseDll','dll',MB_OK or MB_ICONINFORMATION);
        if assigned(Qry) then
        begin
            Qry.Free;
            Qry := nil;
        end;
    end;
    exports
        CloseDll,
        QueryDll,
        InitDll;
    end.
      

  10.   

    这个DLL不用加ShareMem 吧,但是我连续调用的时候就出错!
      

  11.   

    procedure TForm2.Button4Click(Sender: TObject);
    var
        i: integer;
        p: Pchar;
    begin
        for i := 1 to 1000 do
        begin
            p := QueryDll(Pchar(edit1.Text),Pchar(inttostr(i)));
            Memo1.Lines.Add(p);
            application.ProcessMessages;
            Button4.Caption := inttostr(i);
        end;
       ShowMessage('ok');
    end;