我建立的一个Pub.DLL,用于存储一些公用的函数,其中一个如下,用来写入ini文件,问题是:
1,在主程序中调用这个函数,不带包编译的时候,一切正常
2,当主程序带包编译时,界面左上角的程序图标就会变成一个白方块。当然,如果不调用这个函数,即使带包编译也没什么问题,
看来问题就出在这个函数调用上,大家看看为什么会这样:主程序中的调用:
  WriteFile('net','Server_name',cbxDB.Text);dll中的函数:procedure WriteFile(Section:string;KeyWord:string;Value:string);stdcall;
{
 功能:向qc.ini特定字段中写数据
}
var
  qc_ini:Tinifile;
  filename:string;
begin
  filename:= ExtractFilePath(paramstr(0))+'qc.ini';
  qc_ini := Tinifile.Create(filename);
  qc_ini.WriteString(Section,KeyWord,Value);
  qc_ini.Free;
end;

解决方案 »

  1.   

    用pchar代替string做参数, 或者主程序和dll都以sharemm为第一个被引用的单元, 这样主程序和dll要连同borlandmm.dll一同使用
      

  2.   

    不是PCHAR的问题,我把参数都改为Pchar后还是同样的问题
      

  3.   

    在你调用的单元里也加上引用试一下
    uses
     INI files;
      

  4.   

    自己测试了一下,dll中的函数代码如果直接写在主程序中就没什么问题,
    因此我想问题的出现可能是由于调用dll的缘故,大家说说调用dll还有什么其他需要注意的吗?
      

  5.   

    自己测试了一下,dll中的函数代码如果直接写在主程序中就没什么问题,
    因此我想问题的出现可能是由于调用dll的缘故,大家说说调用dll还有什么其他需要注意的吗?
      

  6.   

    建议楼主下载下面网址例子看一下,然后参照它修改你的代码,说实话,你的程序规划不好、代码也乱,先看看例子吧http://www.delphifans.com/SoftView/SoftView_346.html
      

  7.   

    上面例子EXE和DLL都要重新编译,因为作者是用D6做的
      

  8.   

    用stdcall了吗?
    export加了吗?
    external了吗?
    调用dll是用静态还是动态?
      

  9.   

    //未发现程序异常,可能是其它的公用函数产生的异常!//主调
    type
    TWriteFile=procedure(Section:string;KeyWord:string;Value:string);stdcall;procedure Test;
    var
      DllHnd: THandle;
      WriteIni: TWriteFile;
    begin  DllHnd := LoadLibrary(PChar('project1.dll'));
      try
        if (DllHnd <> 0) then
        begin
          @WriteIni :=GetProcAddress(DllHnd, 'WriteFile');
          if (@WriteIni<>nil) then
             WriteIni('abc','cde','abc');
          else
          begin
            application.MessageBox(PChar('DLL加载出错,DLL可能不存在!'), PChar('错误'),
              MB_ICONWARNING or MB_OK);
          end;
        end;
      finally
        FreeLibrary(DllHnd);
      end;
    end;
    //DLL
    procedure WriteFile(Section:string;KeyWord:string;Value:string);stdcall;
    {
     功能:向qc.ini特定字段中写数据
    }
    var
      qc_ini:Tinifile;
      filename:string;
    begin
      filename:= ExtractFilePath(paramstr(0))+'qc.ini';
      qc_ini := Tinifile.Create(filename);
      qc_ini.WriteString(Section,KeyWord,Value);
      qc_ini.Free;
    end;exports
        WriteFile;
      

  10.   

    把Delphi 中的string类型创建与释放的原理理解一下就可以了!
      

  11.   

    不是PCHAR问题……楼主要的正确答案是:
    1、继续维持带包编译
    2、把静态引入DLL改成动态加载DLL,获取导出函数OK!
      

  12.   

    暂时解决了,
    我把所有对公用dll的函数引用都去掉了,把这些函数直接写在主程序种,然后再带包编译就好了,不过真正的原因还没有找出,哎
      

  13.   

    谢谢兄弟,我也觉得自己的代码乱的厉害,现在用你的建议,给每个模块建一个datamodule,这样的确要清晰一些
      

  14.   

    -_- 呃...动态的话,就是指用LoadLibrary的那种方法加载DLL,然后用GetProcAddress获取到处函数的地址,进而进行函数调用。我估计你现在是用External的那种方法获取DLL函数,这种方法称为静态引入。出现你这个情况(主程序白色)的原因是:DLL和EXE中存在两个Application全局变量(这个全局变量位于Forms单元里),网上可以找到很多相关资料说这个问题。共享VCL.BPL正是为了解决这个问题,当EXE初始化后,DLL中访问到的Application也就是EXE的Application了。但是问题出在你静态引入DLL函数这里,因为静态引入也是在EXE初始化的时候就执行,我猜想是这个DLL加载比EXE初始化Application还要早,因此在加载DLL的时候,VCL.BPL中的FORMS单元里的Application全局变量就会被初始化成了DLL中的Application(一个不正确的Application),从而出现你说的EXE图标变白方块的问题(这个问题我遇到过)。所以只要把External那种方式改成动态加载DLL,就可以避免这个问题了。“如果不调用这个函数,即使带包编译也没什么问题”,这个是因为DELPHI编译的时候,会判断你这个函数有没有实际用过,没有的话,就不会把它编译进来。你可以看到当不使用时,External那一行前面的“编译小圆点”是不存在的,也就是没被编译。不过我还是有一点疑问,你这个导出函数按理也没有用到Forms单元。这个我倒是没试过,我之前是DLL用到Forms单元,共享BPL并静态引入导出函数时,主程序会出现你这种情况。或者你可以先试试改成动态加载后,行不行吧。--------------------------------------------------------------这个问题和ShareMem没有关系,引用ShareMem只是为了解决字符串的内存释放的问题,并不会引起楼主说的那种现象。以为一般情况下,字符串是EXE中分配内存的,就必须在EXE中释放;在DLL里分配内存的,就必须在DLL中释放,否则就会出错(invalid pointer operation),所以DLL说明里才会建议用PChar,或者加ShareMem。
      

  15.   

    把静态引入DLL改成动态加载DLL