PowerBuilder调用Delphi写的Dll时发生的奇怪问题

2016-02-19 19:31 38 1 收藏

下面是个PowerBuilder调用Delphi写的Dll时发生的奇怪问题教程,撑握了其技术要点,学起来就简单多了。赶紧跟着图老师小编一起来看看吧!

【 tulaoshi.com - 编程语言 】

因项目需要,我用Delphi写了一个连接数据库把数据导出到Sql文件的dll,其中使用了TADOQuery组件。
  其中只有一个导出方法:
  function DataExport(path,ini_path:PChar):integer
  
    写完之后,用delphi写了一个test.exe进行测试,发现可以正常使用。
  之后便把这个dll交给了同事,让他在PowerBuilder中调用。同事拿过去之后发现,一旦调用DataExportPB就报告无法打开目标Dll。我想可能是因为两边运行的环境不一样,随后就把test.exe拷过去试试看。奇怪的是,test.exe运行正常。
  
    为了确定问题到底出现在哪里,我又使用Python和C#测试了一下,C#下面没有问题,但是Python报告错误:
  查阅资料之后发现,如果在Delphi的Dll里面使用了ADO组件,那么需要在使用之前调用ActiveX的CoInitialize方法。知道了问题之后就好办多了,在源代码中创建TADOQuery之前调用CoInitialize(),Python调用成功。

    本以为PowerBuilder也应该没问题,可谁知还是一样的问题。这下子我想不通了。Python中的ctypes模块使用的C中的调用方法,参数传递方式应该和PowerBuilder一样,可是为什么PB里面还是不行呢?同事让我在Dll里面多写一个输出方法试试看,那好,我又写了下面这样一个方法:

(本文来源于图老师网站,更多请访问http://www.tulaoshi.com/bianchengyuyan/)

  function test:PChar;
  begin
  
  result := 'Test string from test';
  end;

    PB里面调用test方法成功,  接着同事又尝试调用DataExport,成功了!!??为什么?这个test方法仅仅只是输出一段固定的字符串而已,为什么DataExport就调用成功了呢?我真是百思不得其解。

    但是这时又出现一个问题,一旦退出PB应用程序则发生一个内存操作错误。

    我仔细检查了Delphi代码,以图发现是不是哪一个对象没有释放,我的代码如下:

  function DataExport(path,ini_path:PChar):integer;
  var
  
  query : TADOQuery;
  begin
    .........
    CoInitialize();
    query := TADOQuery.Create(nil);
    .........
    query.Close;
    query.Free;
    CoUnInitialize();
    .........
  end;

  没有什么问题啊!无奈之下我把CoInitialize()和CoUnInitialize()分成两个独立方法。
  function init:integer;
  begin
  
  try
  
    CoInitialize();
      result := 1;
    except
  
    on Exception:
        result := 0;
    end;
  
end;

  function uninit:integer;
  begin
    try
      CoUnInitialize();
      result := 1;
    except
      on Exception:
        result := 0;
    end;
  end;

  然后让同事在窗体初始化事件中先调用 init,然后再关闭事件中调用 uninit。问题解决。什么都正常了。

  虽然问题得到解决,但是我还是不明白为什么要这样做。

(本文来源于图老师网站,更多请访问http://www.tulaoshi.com/bianchengyuyan/)

来源:http://www.tulaoshi.com/n/20160219/1621230.html

延伸阅读
  作者:e梦缘 好久发表文章了!!! 调用DLL文件中的FORM,具体实现过程如下: library Project1;uses SysUtils, Classes,Forms,windows,dialogs, Unit1 in 'Unit1.pas' {Form1};{$R *.res}function showform(formname:string):boolean;stdcall;var TheClass: TPersistentClass; aForm: TForm;be...
标签: Delphi
  一 Dll的制作一般步骤 二 参数传递 三 DLL的初始化和退出清理[如果需要初始化和退出清理] 四 全局变量的使用 五 调用静态载入 六 调用动态载入 七 在DLL建立一个TForM 八 在DLL中建立一个TMDIChildForM 九 示例: 十 Delphi制作的Dll与其他语言的混合编程中常遇问题: 十一 相关资料 ...
  unit Unit1; interface uses   Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,   Dialogs, ComCtrls, StdCtrls, ExtCtrls, Grids, Calendar, Gauges, jpeg; type   TForm1 = class(TForm)     Shape1: TShape;    ...
标签: Delphi
  在用Delphi 3.0开发软件时,出现了硬件驱动程序(DLL)中的函数和过程不能正常调用的问题,该硬件由英国Schlumberger公司生产,驱动程序用汇编语言编写的。其《编程指南》给出的Microsoft C的示范程序均能正常运行。但运行此软件时现出的错误提示为: Access violation at address ×××××××× in module…… 经仔细分析...
一 Dll的制作一般分为以下几步: 1 在一个DLL工程里写一个过程或函数 2 写一个Exports关键字,在其下写过程的名称。不用写参数和调用后缀。 二 参数传递 1 参数类型最好与window C++的参数类型一致。不要用DELPHI的数据类型。 2 最好有返回值[即使是一个过程],来报出调用成功或失败,或状态。成功或失败的返回值最好...

经验教程

63

收藏

61
微博分享 QQ分享 QQ空间 手机页面 收藏网站 回到头部