例如我有 TEST.exe和TEST.dll,我想获取TEST.dll中TTWW.pas中的一个变量A
于是我在TEST.dll中这样写use
 TTWWin TTWW.pas' {FrmTTWW},
function Execute: string;
begin
    Result :=A;
end;
{$R *.res}
exports
  Execute;然后exe中接收,代码如下:implementation
  function Execute: string; external 'Dll.dll' name 'Execute';procedure TTWWForm.Button2Click(Sender: TObject);
var
  pExecute: function : string;
  nHandle: THandle;
begin
  nHandle := LoadLibrary('Dll.dll');
  if nHandle <> INVALID_HANDLE_VALUE then
  try
    @pExecute := GetProcAddress(nHandle, 'Execute');
    if Assigned(pExecute) then
      Caption := pExecute();
  finally
    FreeLibrary(nHandle);
  end;
end;可是我exe中接受到的Execute总是为空值. 
当我把DLL中的Execute函数下面这样写是就成功了:function Execute: string;
begin
    Result :='搞笑吧,静态值可以';
end;
请问我这是哪里出错了呢?

解决方案 »

  1.   

    试试这样procedure Execute(var aStr:string);
    begin
        aStr :=A;
    end;另外,既然A是dll中的全局变量,楼主在dll中如何给这个全局变量赋值的呢?
      

  2.   

    为空应该是你没有对A进行赋值,另外你调用DLL的程序里面分别用了动态加载和表态加载DLL的方法,重复了用一种就可以了
      

  3.   

    返回类型为WideString就好了,或者是PChar。
      

  4.   

    我没介绍清楚
    A的值是这样的,我有一个treelist,我在改变node时A的值也会不停变化.
    在dxTreeList1MouseDown事件中赋值了
      

  5.   

    DLL返回string必须要把ShareMem uses在第一位,或者你改用PCHAR吧!还有一个办法,从dll里面向exe发消息,把string地址强转成integer随消息参数发出,到exe中在根据
    地址恢复出string,这个俺经常用。
      

  6.   

    pchar试过 不行 很是费解.....
      

  7.   

    发现我在EXE中读取的Execute值是显示inaccessible value
      

  8.   

    以前在一个高人的博客里看来的,大致意思:delphi里,返回string的函数,有隐含参数,就是返回的string地址,也就是说,返回的string,仍然是调用者分配空间的,否则,函数内创建的局部变量,在函数结束后就释放了,调用者怎么可能获得?而静态赋值的变量和动态赋值的变量地址空间不同,函数结束也存在,所以要在dll里返回string,必须uses sharemem。
      

  9.   

    还有一种办法,你从exe中传递一个字符数组的指针给dll的execute函数,然后用StrLCopy把A的值Copy到指针所指向的字符数组,
    dll的修改大致如下:
    function Execute(pRet:PChar,nLen:Integer): string;
    begin
        //Result :=A;
        StrLCopy(pRet,A,nLen);
    end;然后在exe调用的时候先声明一个字符数组,把数组指针和长度传递给Execute,当然需要考虑好数组的大小要足够保存A的字符串的值了
      

  10.   

      实际上,我用了Lsuper_D7_FastMM_RTL_Patch_v1.0这个补丁,替换了D7原来的内存管理器,理论上不用uses sharemem了.
      

  11.   

    这都什么跟什么啊,在哪个 dxTreeList1MouseDown 事件中?每次都把dll卸掉,再装载个新的出来,它不给你初始化成空字符串还能是什么?to 15楼:
    你的转述的东西只有前一半是靠谱的,后面的结论跟为什么引用ShareMem根本没关系。
    由于各个module都有自己的memory manager,所以由rtl自动管理生存期的变量会出现由module A分配内存,却在module B中生存期结束由B的mm释放内存的情况。引用ShareMem或者使用fastmm的目的只有一个,就是让不同module使用同一个mm,这样就不会出现不同的mm无法管理其它module自动生存期类型的释放问题
      

  12.   

    dll中接口函数中有
    string类型时需要uses sharemem并且放在第一个