library工程:
Dll 输出 GetResultfunction GetResult(AppHandle: THandle): TDataSet;
begin
    Application.handle:= AppHandle;
    DataModule1:= TDataModule1.Create(application);
    result:= DataModule1.ADODataSet1;
end;program工程:
type
  TGetResult = function (AppHandle: THandle): TDataSet; stdcall;
procedure TForm1.Button1Click(Sender: TObject);
var
  DllLib: THandle;
  GetResult: TGetResult;
begin
  try
    DllLib:= LoadLibrary('prjDll');
    if DllLib <> 0 then
      @GetResult:= GetProcAddress(DllLib, 'GetResult');
    if @GetResult <> nil then
      DataSource1.DataSet:= GetResult(Application.Handle);// ???
  finally
    FreeLibrary(dllLib);
  end;
当运行到上面一句时,弹出prjUserDll.exe Raise Exception Class EInvalidPointer with message 'Invalid pointer operation', process stopped.
User Step or Run to continue.
请问这是怎么回事?该怎样解决?谢谢!!!

解决方案 »

  1.   

    我曾碰到你这个问题,解决办法为:
    你不应该将你的创建DataModule在调用GetResult时才开始,你应该在执行LoadLibrary时就应该创建DataModule,你可以在library工程中加在以下代码procedure CreateMDL;
    begin
      DataModule1:= TDataModule1.Create(application);
    end;
    function GetResult(AppHandle: THandle): TDataSet;
    begin
        Application.handle:= AppHandle;    
        result:= DataModule1.ADODataSet1;
    end;initialization
      CreateMDL;
    end;
      

  2.   

    To Wally_wu(不想再写代码):
    我在GetResult函数所在的单元加上了
    procedure CreateMDL;
    begin
      DataModule1:= TDataModule1.Create(application);
    end;initialization
      CreateMDL;
    但还是出现同样的错误提示?
      

  3.   

    请在工程文件的第一个引用单元之前加上ShareMem单元的引用,详细原因你用向导创建一个DLL工程,看一下上面一大段英文介绍即会明白
      

  4.   

    谢谢楼上各位!
    To  daniel007(添):
    我想问一下:需要引用ShareMem单元时,ShareMem单元是否只需作为program和library工程文件的第一个引用单元就行?引用和被引用的具体单元的引用单元里无需添加ShareMem单元?
      

  5.   

    引用ShareMem,的确要将要ShareMem添加到引用和被引用模块中,并且要是第一个引用单元。所以应该是dpr文件的第一个uses单元。    不过,实现可执行模块之间共享对象的最好方法是,所有模块都采用包编译模式(Build with runtime packages)。这样,什么东西都不用添加。李战.深圳
      

  6.   

    在我的电脑上运行正常呀!这样吧,为了保证正常运常,你再创建一个package, 使用"Built with runtime packages",将你的代码
    type
      TGetResult = function (AppHandle: THandle): TDataSet; stdcall;GetResult: TGetResult;
    procedure loadproject;
    var
      DllLib: THandle;
    begin
      try
        DllLib:= LoadLibrary('prjDll');
        if DllLib <> 0 then
          @GetResult:= GetProcAddress(DllLib, 'GetResult');
      except
        FreeLibrary(dllLib);
      end;
    end;然后再用你的project静态调用它:
    procedure TForm1.Button1Click(Sender: TObject);
    begin
      try
        if @GetResult <> nil then
          DataSource1.DataSet:= GetResult(Application.Handle);
      finally
        FreeLibrary(dllLib);
      end;
    end;
      

  7.   

    在我的电脑上运行正常呀!这样吧,为了保证正常运常,你再创建一个package, 使用"Built with runtime packages",将你的代码
    type
      TGetResult = function (AppHandle: THandle): TDataSet; stdcall;var
    GetResult: TGetResult;
    DllLib: THandle;
    procedure loadproject;
    begin
      try
        DllLib:= LoadLibrary('prjDll');
        if DllLib <> 0 then
          @GetResult:= GetProcAddress(DllLib, 'GetResult');
      except
        FreeLibrary(dllLib);
      end;
    end;
    放到Package的单元里;然后再用你的project静态调用它:
    procedure TForm1.Button1Click(Sender: TObject);
    begin
      try
        if @GetResult <> nil then
          DataSource1.DataSet:= GetResult(Application.Handle);
      finally
        FreeLibrary(dllLib);
      end;
    end;
      

  8.   

    谢谢 Wally_wu(不想再写代码)
    暂时解决我调用Dll的困惑。
    我另开贴,希望楼上各位参与。