程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> 更多編程語言 >> Delphi >> PowerBuilder調用Delphi寫的Dll時發生的奇怪問題

PowerBuilder調用Delphi寫的Dll時發生的奇怪問題

編輯:Delphi
因項目需要,我用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報告錯誤:
  沒有調用 CoInitialize()
  
查閱資料之後發現,如果在Delphi的Dll裡面使用了ADO組件,那麼需要在使用之前調用ActiveX的CoInitialize方法。知道了問題之後就好辦多了,在源代碼中創建TADOQuery之前調用CoInitialize(),Python調用成功。

    本以為PowerBuilder也應該沒問題,可誰知還是一樣的問題。這下子我想不通了。Python中的ctypes模塊使用的C中的調用方法,參數傳遞方式應該和PowerBuilder一樣,可是為什麼PB裡面還是不行呢?同事讓我在Dll裡面多寫一個輸出方法試試看,那好,我又寫了下面這樣一個方法:

  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。問題解決。什麼都正常了。

  雖然問題得到解決,但是我還是不明白為什麼要這樣做。


  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved