delphi 如何能把dll写进资源,生产.exe,并且调用时释放出来 
                   
    基础不好,希望大牛别见笑,回答的时候写的相信点,谢谢!!!

解决方案 »

  1.   

    delphi制作资源文件和释放资源文件的方法 
    首先先制作资源文件如何制作呢?AAA EXEFILE AAA.exe   把这段文字复制到个记事本里保存为AAA.rcAAA为在程序里调用资源文件的名字   就是给资源文件起个名字在程序里调用EXEFILE   为文件类型   意思是exe文件AAA.EXE   为你要做成资源的exe文件在写个批处理文件内容为 
    path=C:\Program Files\Borland\Delphi7\Bin;      
    Brcc32 AAA.rc
    第一行是你delphi的安装目录下的bin目录下的Brcc32.exe的位置   因为要用brcc32.exe编译第二行的AAA.rc为 你刚才写的rc文件的文件名把以上两个文件和你要做成资源文件的exe放在一个目录下   执行批处理  这时候会多出   AAA.res
    我们到delphi中新建个application   往上面放上一个按钮   点那个按钮的时候释放资源文件并且运行程序       要把AAA.res   放到工程目录下   就是你这个程序保存的地方!代码如下unit Unit1;interfaceuses
       Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
       Dialogs, StdCtrls, Buttons,shellapi;     //shellapi引用   api函数来运行程序type
       TForm1 = class(TForm)
         BitBtn1: TBitBtn;
         procedure BitBtn1Click(Sender: TObject);
       private
         { Private declarations }
       public
         { Public declarations }
       end;var
       Form1: TForm1;implementation{$R *.dfm}
    {$R 'AAA.RES'}     //这里调用得写上你的RES文件的名字
    procedure ExtractRes(ResType, ResName, ResNewName : String);
    var
    Res : TResourceStream;
    begin
    Res := TResourceStream.Create(Hinstance, Resname, Pchar(ResType));
    Res.SavetoFile(ResNewName);
    Res.Free;
    end;                         //这个方法意思是释放资源文件   有三个参数 
                                   //一个资源类型   2 资源名字   生成资源的名字
    procedure TForm1.BitBtn1Click(Sender: TObject);
    begin
         ExtractRes('EXEFILE', 'AAA', 'AAA.exe');   //这里调用函数释放资源     showmessage('释放成功');     // 弹出个对话框 可以不写 没啥用 只是提示一下
         sleep(1000);     //让程序 休眠1秒
         ShellExecute(0, nil, 'AAA.exe',nil, nil,sw_show);   //运行程序 带的四个参数不用管他 
    //如果要是想隐藏运行把最后那个参数改为   SW_HIDE 就OK了  end;end.
      

  2.   


    楼上正确,DLL释放的时候还可以直接释放到内存中。
      

  3.   

    http://www.foolcode.com/?p=482 有一个资源文件的详解是我两年前搜集整理的~希望对你有帮助
      

  4.   

    看来我问错了。。嘿嘿。,我是想表达,是这样的,一个dll写进资源不释放出来直接调用。以前看过的,pe头直接加载的,我问错了。
      

  5.   

    DLL可以直接做到EXE中,而EXE在使用DLL时不用释放,可直接引用DLL里面的函数。
    你给分太少,否则代码直接奉上。
      

  6.   

    //从内存中加载DLL DELPHI版  
    unit MemLibrary;interfaceuses
    Windows;
    function memLoadLibrary(pLib: Pointer): DWord;
    function memGetProcAddress(dwLibHandle: DWord; pFunctionName: PChar): Pointer; stdcall;
    function memFreeLibrary(dwHandle: DWord): Boolean;
    implementationprocedure ChangeReloc(baseorgp, basedllp, relocp: pointer; size: cardinal);
    type
        TRelocblock = record
            vaddress: integer;
            size: integer;
        end;
        PRelocblock = ^TRelocblock;
    var
        myreloc: PRelocblock;
        reloccount: integer;
        startp: ^word;
        i: cardinal;
        p: ^cardinal;
        dif: cardinal;
    begin
        myreloc := relocp;
        dif := cardinal(basedllp)-cardinal(baseorgp);
        startp := pointer(cardinal(relocp)+8);
        while myreloc^.vaddress <> 0 do
        begin
          reloccount := (myreloc^.size-8) div sizeof(word);
          for i := 0 to reloccount-1 do
          begin
            if (startp^ xor $3000 < $1000) then
            begin
              p := pointer(myreloc^.vaddress+startp^ mod $3000+integer(basedllp));
              p^ := p^+dif;
            end;
            startp := pointer(cardinal(startp)+sizeof(word));
          end;
          myreloc := pointer(startp);
          startp := pointer(cardinal(startp)+8);
        end;
    end;
    procedure CreateImportTable(dllbasep, importp: pointer); stdcall;
    type
        timportblock = record
              Characteristics: cardinal;
              TimeDateStamp: cardinal;
              ForwarderChain: cardinal;
              Name: pchar;
              FirstThunk: pointer;
        end;
        pimportblock = ^timportblock;
    var
        myimport: pimportblock;
        thunksread, thunkswrite: ^pointer;
        dllname: pchar;
        dllh: thandle;
        old: cardinal;
    begin
        myimport := importp;
        while (myimport^.FirstThunk <> nil) and (myimport^.Name <> nil) do
        begin
          dllname := pointer(integer(dllbasep)+integer(myimport^.name));
          dllh := LoadLibrary(dllname);
          thunksread := pointer(integer(myimport^.FirstThunk)+integer(dllbasep));
          thunkswrite := thunksread;
          if integer(myimport^.TimeDateStamp) = -1 then
            thunksread := pointer(integer(myimport^.Characteristics)+integer(dllbasep));
          while (thunksread^ <> nil) do
          begin
            if VirtualProtect(thunkswrite,4,PAGE_EXECUTE_READWRITE,old) then
            begin
              if (cardinal(thunksread^) and $80000000 <> 0) then
              thunkswrite^ := GetProcAddress(dllh,pchar(cardinal(thunksread^) and $FFFF)) else
              thunkswrite^ := GetProcAddress(dllh,pchar(integer(dllbasep)+integer(thunksread^)+2));
              VirtualProtect(thunkswrite,4,old,old);
            end;
            inc(thunksread,1);
            inc(thunkswrite,1);
          end;
          myimport := pointer(integer(myimport)+sizeof(timportblock));
        end;
    end;
    function memLoadLibrary(pLib: Pointer): DWord;
    var
    DllMain    : function (dwHandle, dwReason, dwReserved: DWord): DWord; stdcall;
    IDH        : PImageDosHeader;
    INH        : PImageNtHeaders;
    SEC        : PImageSectionHeader;
    dwSecCount : DWord;
    dwLen      : DWord;
    dwmemsize : DWord;
    i          : Integer;
    pAll       : Pointer;
    begin
    Result := 0;IDH := pLib;
    if isBadReadPtr(IDH, SizeOf(TImageDosHeader)) or (IDH^.e_magic <> IMAGE_DOS_SIGNATURE) then
        Exit;INH := pointer(cardinal(pLib)+cardinal(IDH^._lfanew));
    if isBadReadPtr(INH, SizeOf(TImageNtHeaders)) or (INH^.Signature <> IMAGE_NT_SIGNATURE) then
        Exit;// if (pReserved <> nil) then
    //    dwLen := Length(pReserved)+1
    // else
        dwLen := 0;SEC := Pointer(Integer(INH)+SizeOf(TImageNtHeaders));
    dwMemSize := INH^.OptionalHeader.SizeOfImage;
    if (dwMemSize = 0) then Exit;pAll := VirtualAlloc(nil,dwMemSize+dwLen,MEM_COMMIT or MEM_RESERVE,PAGE_EXECUTE_READWRITE);
    if (pAll = nil) then Exit;dwSecCount := INH^.FileHeader.NumberOfSections;
    CopyMemory(pAll,IDH,DWord(SEC)-DWord(IDH)+dwSecCount*SizeOf(TImageSectionHeader));
    // CopyMemory(Pointer(DWord(pAll) + dwMemSize),pReserved,dwLen-1);
    CopyMemory(Pointer(DWord(pAll) + dwMemSize),nil,dwLen-1);
    for i := 0 to dwSecCount-1 do
    begin
        CopyMemory(Pointer(DWord(pAll)+SEC^.VirtualAddress),
              Pointer(DWord(pLib)+DWord(SEC^.PointerToRawData)),
              SEC^.SizeOfRawData);
        SEC := Pointer(Integer(SEC)+SizeOf(TImageSectionHeader));
    end;if (INH^.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress <> 0) then
        ChangeReloc(Pointer(INH^.OptionalHeader.ImageBase),
              pAll,
              Pointer(DWord(pAll)+INH^.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress),
              INH^.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].Size);
    CreateImportTable(pAll, Pointer(DWord(pAll)+INH^.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress));@DllMain := Pointer(INH^.OptionalHeader.AddressOfEntryPoint+DWord(pAll));
    // if (INH^.OptionalHeader.AddressOfEntryPoint <> 0) and (bDllMain) then
    if INH^.OptionalHeader.AddressOfEntryPoint <> 0 then
    begin
        try
    //      if (pReserved <> nil) then
    //        DllMain(DWord(pAll),DLL_PROCESS_ATTACH,DWord(pAll)+dwMemSize)
    //      else
            DllMain(DWord(pAll),DLL_PROCESS_ATTACH,0);
        except
        end;
    end;
    Result := DWord(pAll);
    end;
    function memFreeLibrary(dwHandle: DWord): Boolean;
    var
    IDH: PImageDosHeader;
    INH: PImageNTHeaders;
    begin
    Result := false;
    if (dwHandle = 0) then
        Exit;IDH := Pointer(dwHandle);
    if (IDH^.e_magic <> IMAGE_DOS_SIGNATURE) then
        Exit;INH := Pointer(DWord(IDH^._lfanew)+DWord(IDH));
    if (INH^.Signature <> IMAGE_NT_SIGNATURE) then
        Exit;if VirtualFree(Pointer(dwHandle),INH^.OptionalHeader.SizeOfImage,MEM_DECOMMIT) then
        Result := True;
    end;
    function memGetProcAddress(dwLibHandle: DWord; pFunctionName: PChar): Pointer; stdcall;
    var
    NtHeader          : PImageNtHeaders;
    DosHeader          : PImageDosHeader;
    DataDirectory      : PImageDataDirectory;
    ExportDirectory    : PImageExportDirectory;
    i          : Integer;
    iExportOrdinal     : Integer;
    ExportName         : String;
    dwPosDot          : DWord;
    dwNewmodule        : DWord;
    pFirstExportName   : Pointer;
    pFirstExportAddress: Pointer;
    pFirstExportOrdinal: Pointer;
    pExportAddr        : PDWord;
    pExportNameNow     : PDWord;
    pExportOrdinalNow : PWord;
    begin
    Result := nil;
    if pFunctionName = nil then Exit;DosHeader := Pointer(dwLibHandle);
    if isBadReadPtr(DosHeader,sizeof(TImageDosHeader)) or (DosHeader^.e_magic <> IMAGE_DOS_SIGNATURE) then
        Exit; {Wrong PE (DOS) Header}NtHeader := Pointer(DWord(DosHeader^._lfanew)+DWord(DosHeader));
    if isBadReadPtr(NtHeader, sizeof(TImageNTHeaders)) or (NtHeader^.Signature <> IMAGE_NT_SIGNATURE) then
        Exit; {Wrong PW (NT) Header}DataDirectory := @NtHeader^.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT];
    if (DataDirectory = nil) or (DataDirectory^.VirtualAddress = 0) then
        Exit; {Library has no exporttable}ExportDirectory := Pointer(DWord(DosHeader) + DWord(DataDirectory^.VirtualAddress));
    if isBadReadPtr(ExportDirectory,SizeOf(TImageExportDirectory)) then
        Exit;pFirstExportName := Pointer(DWord(ExportDirectory^.AddressOfNames)+DWord(DosHeader));
    pFirstExportOrdinal := Pointer(DWord(ExportDirectory^.AddressOfNameOrdinals)+DWord(DosHeader));
    pFirstExportAddress := Pointer(DWord(ExportDirectory^.AddressOfFunctions)+DWord(DosHeader));if (integer(pFunctionName) > $FFFF) then {is FunctionName a PChar?}
    begin
        iExportOrdinal := -1;          {if we dont find the correct ExportOrdinal}
        for i := 0 to ExportDirectory^.NumberOfNames-1 do {for each export do}
        begin
          pExportNameNow := Pointer(Integer(pFirstExportName)+SizeOf(Pointer)*i);
          if (not isBadReadPtr(pExportNameNow,SizeOf(DWord))) then
          begin
            ExportName := PChar(pExportNameNow^+ DWord(DosHeader));
            if (ExportName = pFunctionName) then {is it the export we search? Calculate the ordinal.}
            begin
              pExportOrdinalNow := Pointer(Integer(pFirstExportOrdinal)+SizeOf(Word)*i);
              if (not isBadReadPtr(pExportOrdinalNow,SizeOf(Word))) then
              iExportOrdinal := pExportOrdinalNow^;
            end;
          end;
        end;
    end else{no PChar, calculate the ordinal directly}
        iExportOrdinal := DWord(pFunctionName)-DWord(ExportDirectory^.Base);if (iExportOrdinal < 0) or (iExportOrdinal > Integer(ExportDirectory^.NumberOfFunctions)) then
        Exit; {havent found the ordinal}pExportAddr := Pointer(iExportOrdinal*4+Integer(pFirstExportAddress));
    if (isBadReadPtr(pExportAddr,SizeOf(DWord))) then
        Exit;{Is the Export outside the ExportSection? If not its NT spezific forwared function}
    if (pExportAddr^ < DWord(DataDirectory^.VirtualAddress)) or
         (pExportAddr^ > DWord(DataDirectory^.VirtualAddress+DataDirectory^.Size)) then
    begin
        if (pExportAddr^ <> 0) then {calculate export address}
          Result := Pointer(pExportAddr^+DWord(DosHeader));
    end
    else
    begin {forwarded function (like kernel32.EnterCriticalSection -> NTDLL.RtlEnterCriticalSection)}
        ExportName := PChar(dwLibHandle+pExportAddr^);
        dwPosDot := Pos('.',ExportName);
        if (dwPosDot > 0) then
        begin
          dwNewModule := GetModuleHandle(PChar(Copy(ExportName,1,dwPosDot-1)));
          if (dwNewModule = 0) then
            dwNewModule := LoadLibrary(PChar(Copy(ExportName,1,dwPosDot-1)));
          if (dwNewModule <> 0) then
            result := GetProcAddressX(dwNewModule,PChar(Copy(ExportName,dwPosDot+1,Length(ExportName))));
        end;
    end;
    end;end.