为什么我用静态调用 DLL 里面的函数就没有问题, 如改用动态调用就出现如下问题
(存取地址00403E46违例发生在模块 'Project1.exe'中, 读在地址00D71E68里.)
源码如下:主程序文件:
type
  TLanCardID = function:string;stdcall;
  TGetNetBIOSAddress = function:string;stdcall;procedure TForm1.Button1Click(Sender: TObject);
var
  proc:TLanCardID;
  aptr:TFarproc;
  Moudle:THandle;
  s:string;
begin
  Moudle:= Loadlibrary('IntDLL.dll');
  if Moudle <> 0 then
    try
      begin
        aptr:= GetProcAddress(Moudle,'GetIP');
        if aptr <> nil then
          begin
            proc:=TLanCardID(aptr);
            s := proc;
            Edit1.Text:= '本机IP地址: '+ s;
          end;
      end;
    finally
      Freelibrary(Moudle);
    end;
end;procedure TForm1.Button5Click(Sender: TObject);
var
  proc1:TGetNetBIOSAddress;
  aptr1:TFarproc;
  Moudle1:Integer;
  s1:string;
begin
  Moudle1:= Loadlibrary('IntDLL.dll');
  if Moudle1 <> 0 then
    try
      begin
        aptr1:= GetProcAddress(Moudle1,'GetNetBIOSAddress');
        if aptr1 <> nil then
          begin
            proc1:=TGetNetBIOSAddress(aptr1);
            s1 := proc1;
            Edit3.Text:= 'NetBios地址: '+ s1;
          end;
      end;
    finally
      Freelibrary(Moudle1);
    end;
end;
DLL文件:
library IntDLL;uses
  SysUtils,
  Classes,
  netfun in 'netfun.pas';{$R *.res}exports
  GetNetBIOSAddress, 
  GetIP;begin
end.////////////////////////////////////
netfun文件:
unit netfun;interfaceuses
  Windows, Messages, SysUtils, Variants, Classes, Graphics,Controls,      
Forms, Dialogs, wininet, Winsock, NB30, Registry, ActiveX;function GetNetBIOSAddress : string;stdcall;function GetIP:string;stdcall;implementationfunction GetNetBIOSAddress : string;stdcall;
var
  ncb  : TNCB;
  status  : TAdapterStatus;
  lanenum : TLanaEnum;  procedure ResetAdapter (num : char);
  begin
    fillchar(ncb,sizeof(ncb),0);
    ncb.ncb_command:=char(NCBRESET);
    ncb.ncb_lana_num:=num;
    Netbios(@ncb);
  end;var
  lanNum  : char;
  address : record
             part1 : Longint;
             part2 : Word;//Smallint;
            end absolute status;
begin
  Result:='';  fillchar(ncb,sizeof(ncb),0);
    ncb.ncb_command:=char(NCBENUM);
    ncb.ncb_buffer:=@lanenum;
    ncb.ncb_length:=sizeof(lanenum);
  Netbios(@ncb);  if lanenum.length=#0 then exit;
  lanNum:=lanenum.lana[0];  ResetAdapter(lanNum);  fillchar(ncb,sizeof(ncb),0);
    ncb.ncb_command:=char(NCBASTAT);
    ncb.ncb_lana_num:=lanNum;
    ncb.ncb_callname[0]:='*';
    ncb.ncb_buffer:=@status;
    ncb.ncb_length:=sizeof(status);
  Netbios(@ncb);
  ResetAdapter(lanNum);  Result:=Format('%x%x',[address.part1,address.part2]);
end;function GetIP:string;stdcall;
var
  WSAData:TWSAData;
  HostName:array[0..MAX_COMPUTERNAME_LENGTH] of Char;
  HostEnt:PHostEnt;
  LastIP:PInAddr; 
  IPList:^PInAddr; 
begin 
  result:=''; 
  if 0=WSAStartup(MAKEWORD(1,1), WSAData) then 
    try
      if 0=gethostname(HostName, MAX_COMPUTERNAME_LENGTH+1) then
        begin
          HostEnt:=gethostbyname(HostName);
          if HostEnt<>nil then
            begin
              IPList:=Pointer(HostEnt^.h_addr_list);
              repeat
                LastIP:=IPList^;
                INC(IPList);
              until
               IPList^=nil;
              if LastIP<>nil then
                result:=inet_ntoa(LastIP^);
            end;
        end;
      finally
        WSACleanup;
      end;
end;end.

解决方案 »

  1.   

    DLL用了string要加sharemem,不过强烈建议用PChar.............
      

  2.   

    TO:jjyy2003(威子) 到底在哪一个文件上加, 是执行文件的工程文件, 或是DLL的工程文件????
      

  3.   

    字符串string用 pchar类型代替!
      

  4.   

    TO:jjyy2003(威子) , bingbing2008(冰冰) 如下函数如用 pchar 类型代替字符串 string ????function LanCardID: String;stdcall;
    var
      guid: TGUID;
      i: integer;
    begin
      result := '';
      CoCreateGUID(guid);
      for i := Low(guid.D4)+2 to High(guid.D4) do
        begin
          result := result + IntTohex(guid.D4[i],2);
        end;
    end;
      

  5.   

    最后加一句
     result := PChar(result);
      

  6.   

    把sharemem作为DLL工程的第一个引用单元........
      

  7.   

    TO:jjyy2003(威子) result := PChar(result);不行!!!
      

  8.   

    我都试过了
    可以啊
    函数返回值也改为PChar........
      

  9.   

    TO:jjyy2003(威子)你能否把你改好的代码放出来看看???