本帖最后由 RUILONG88 于 2010-08-03 16:16:59 编辑

解决方案 »

  1.   

    别老要现成的,先学学怎么用dll,返回字符串也就是个function而已
      

  2.   

    1#
    是因为dll中的字符串传递不到主窗体中去呀...
      

  3.   

    字符串未必要用string来传递,你从来不用PCHAR的么?
      

  4.   

    3#
    当然是用PCHAR传递,可还是在主窗体中不能调用显示DLL字符...
      

  5.   

    调用函数之前要GetMem给PChar分配内存空间的,做过了没
      

  6.   

    比如你DLL里面的函数是function GetStr(Str: PChar): integer;主程序里就是:var
      TestStr: PChar;
    begin
      GetMem(TestStr, 100); //字符串长度,自己设置
      GetStr(TestStr);
      //使用
      FreeMem(TestStr);
    end;
      

  7.   

    7#
    请你说说"DLL里面的函数是function GetStr(Str: PChar): integer;"的具体代码,好吗
      

  8.   

    DLL自动删除代码如下:#include <windows.h>
    #include <tchar.h>HMODULE hDll;extern "C" __declspec(dllexport) void DeleteMe()
    {
        //在这里干其它想干的事,如删除其它exe文件    //下面代码实现DLL自删除
        TCHAR* szDll = (TCHAR*)VirtualAlloc(NULL, MAX_PATH, MEM_COMMIT, PAGE_READWRITE);
        GetModuleFileName(hDll, szDll, MAX_PATH);    __asm
        {
            push 0        ;参数1
            push 0
            push szDll      ;参数2
            push ExitProcess
            push hDll      ;参数3
            push DeleteFile
            push FreeLibrary
            ret          
        }
    }BOOL APIENTRY DllMain(HMODULE hModule, DWORD  ul_reason_for_call, LPVOID lpReserved)
    {
        switch (ul_reason_for_call)
        {
        case DLL_PROCESS_ATTACH:
               hDll = hModule;
               break;
        case DLL_PROCESS_DETACH:
               break;
        }
        return TRUE;
    }将代码编译为test.dll,然后rundll32 test.dll,DeleteMe运行,test.dll就自己删除了那段__asm代码就是精华所在了执行ret后,就返回到FreeLibrary处去执行,这时候ESP+4就是FreeLibrary的参数,也就是相当于调用了FreeLibrary(参数3),而参数3是DLL自身的模块句柄,所以相当于DLL自己把自己从rundll32.exe里给卸载了;FreeLibrary执行完后会将参数3出栈,并返回到DeleteFile处去执行,这时相当于调用了DeleteFile(参数2),参数2就是DLL文件自身的路径啦,这个路径必须存放在用VirtualAlloc在rundll32.exe里分配的内存,因为这时DLL已经被卸载了;同理最后调用的是ExitProcess(参数1),防止rundll32继续运行下去出错。这样DLL就可以实现自删除啦,这有啥用捏?借助这个DLL,可以实现EXE的自删除,例如把这个DLL放到一个EXE里,当EXE需要自删除的时候,先释放出DLL,然后把EXE自身的路径告诉DLL,最后CreateProcess  rundll32 xxx.dll,DeleteMe,DeleteMe里先删除EXE,再自删除,就可以实现EXE的自删除啦Delphi & VC 回調函數應用教學
      

  9.   

    呵呵,越来越跑题了哦
    如何动态加载dll并且获得dll中指定的某个函数的地址并调用之,这些是基础,如果你不会,那建议你还是先看看相关方面的书再着手使用dll,否则你将面临非常多的问题。至于从dll中传出来字符串并让你使用,下面是一种方式,你可以参考exe中var
      TestStr: PChar;
    begin
      GetMem(TestStr, 100); //字符串长度,自己设置
      GetStr(TestStr, 100);
      //使用
      ShowMessage(TestStr);  FreeMem(TestStr);
    end;其中 GetStr 是Dll中导出的函数。**************************************
    dll中function GetStr(Value: PChar; Len: Integer): Integer;
    var
      I: Integer;
    begin
      for i := 0 to Len - 1 do
      begin
        Value[i] := Char((I mod 26) + 65);
      end;
      Result := 0;
    end;
    上面的程序中,在EXE中申请一块内存,并将内存首地址传递给dll,在dll中操作这块内存,然后回到exe中使用并释放。
      

  10.   

    14#
    GetStr(TestStr, 100);
    该句编译出错:"')' expected but ',' found"?
      

  11.   

    type
      //调用DLL中的报表设计器
      TShowReportDesigner = function (AHandle: THandle; AValue: PChar):Boolean; stdcall; 实现var
        AWindow:IWindow;
        AParentWindow:IParentWindow;
        DllHandle: THandle;
        ShowReportDesigner: TShowReportDesigner;
        DllFileName: string;
      begin
          DllFileName := FControler.JRApp.ExePath+'\Share\ReportSetup.dll';
          DllHandle := LoadLibrary(PChar(DllFileName));
          try
              if DllHandle = 0 then Exit;
              @ShowReportDesigner := GetProcAddress(DllHandle,'ShowReportSetup');
              if Assigned(@ShowReportDesigner) then
              begin
                  if ShowReportDesigner(Application.Handle,PChar(ATemplate)) then
                  begin
                      FControler.GetWindowAndParent(GetName,AWindow,AParentWindow);
                      WindowChanged(FControler,AWindow);
                  end;
              end;
          finally
              FreeLibrary(DllHandle);
          end;
      end;
      

  12.   

    14#
    在delphi7中,如何动态调用DLL返回字符串?
    请说明⑴DLL中给主窗体传递字符串的代码;
      ⑵主窗体中调用并显示DLL传递来的字符串的代码.
    你能分别列出较完整代码吗?谢谢!
      

  13.   

    如果非要用string的话DLL及调用程序必须引用ShareMem,而且必须在第一个引用
      

  14.   

    19#
    在动态调用DLL前提下,希望提供既可以使用返回string,还可以使用返回PCHAR,你能分别提供完整的代码吗?
    本人一直用PB,DELPHI刚开始用,谢谢啦。
      

  15.   

    library TestDll;{ 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,
      Forms,
      Windows;function func:string;stdcall;
    begin
      Result:='Hello world!';
    end;
    exports
    func;end.
      

  16.   


    //工程文件
    library exeTest;
    uses
      ShareMem
    ....
    //调用
    type
    Tfunc=function:string;stdcall;
    var
    fh:THandle;
    f:TFunc;
    begin
      fh:=LoadLibrary('dllTest.DLL');
      if fh>0 then
      begin
        try
          ShowMessage(f());
          finally
            FreeLibrary(fh);
          end;
      end;
    end;
      

  17.   

    Delphi的string在C++/C/C#是不认的,你能用PAnsiChar来代替
    funtion d():PAnsiChar;
    var
    s:string;
    begin
    s:='123';
    result:=PAnsiChar(s);
    end;你再Delphi必须这样写
      

  18.   

    Delphi的string在C++/C/C#是不认的,你能用PAnsiChar来代替
    funtion d():PAnsiChar;stdcall;
    implementation
    funtion d():PAnsiChar;
    var
    s:string;
    begin
    s:='123';
    result:=PAnsiChar(s);
    end;你再Delphi必须这样写
      

  19.   

    唉!
    要学会自己学习啊。
    exe中type
      TDllFun = function (TestStr: PChar; Len: Integer): Integer;
    procedure TForm1.Button2Click(Sender: TObject);
    var
      GetStr: TDllFun;
      Dllhandle: HMODULE;
      TestStr: PChar;begin
      Dllhandle := LoadLibrary('Project2.dll');
      if Dllhandle <> 0 then
      begin
        try
          GetStr := GetProcAddress(Dllhandle, 'GetStr');      GetMem(TestStr, 100); //字符串长度,自己设置      GetStr(TestStr, 100);
          //使用
          ShowMessage(TestStr);      FreeMem(TestStr);
        finally
          FreeLibrary(Dllhandle);
        end;
      end;
    end;Dll中function GetStr(TestStr: PChar; Len: Integer): Integer;
    var
      i: Integer;
    begin
      for i := 0 to Len - 2 do
        TestStr[i] := Char((I mod 26) + 65);
      TestStr[Len - 1] := #0;
      Result := 0;
    end;exports
      GetStr;
      

  20.   

    少写一句
    @f:=GetProcAddress(fh,'func');
    ShowMessage(f());
      

  21.   

    一般情况下,dll和exe之间,最好遵循谁申请谁释放的原则。另外dll和exe之间最好只传递标准数据类型,如果一定要传递自定义类型或者字符串等复杂数据类型,那最好是在exe中申请内存,然后传递指针,然后在dll中操作,然后在exe中释放,或者使用回调函数
      

  22.   

    奇怪 我用了上门2位大哥的代码后, 是可以从dll传递字串给exe显示, 可是在exe窗体关闭时候, 报错 error 217 
    咋回事