全國最多中醫師線上諮詢網站-台灣中醫網
發文 回覆 瀏覽次數:1922
推到 Plurk!
推到 Facebook!

有關delphi呼叫vb的dll問題

答題得分者是:Vicen
perry722
一般會員


發表:27
回覆:11
積分:7
註冊:2004-05-05

發送簡訊給我
#1 引用回覆 回覆 發表時間:2005-03-24 10:35:54 IP:202.175.xxx.xxx 未訂閱
各位大大: 昨天post了一篇有關呼叫vb的dll的帖, mine解答了我一部份的問題, 但還是有些地解決不了,希望各位可以幫忙. 我現在有一個用vb寫的dll (abc.dll) ,請問如何可以在delphi里正確呼叫它呢,mine提供了有關的資料,找到以下的內容: uses Comobj; var obj: Variant; begin obj := CreateOleObject('abc.dll'); .... obj := UnAssigned; end; 我把剛才的code放到formcreate中,但我無法正常運行程序,是否要放到別的地方才可以應用呢?因為是新手, 所以對這方面沒有太多的認識.如何可以的話,請詳細說明這種方法的用法.謝謝 1437
------
1437
wyndog
資深會員


發表:7
回覆:362
積分:348
註冊:2004-10-12

發送簡訊給我
#2 引用回覆 回覆 發表時間:2005-03-24 10:48:16 IP:60.248.xxx.xxx 未訂閱
DLL 的使用,大致上就有二種 一種是,傳統類似 API 庫那樣的 還有一種是 COM 的 不曉得你的 DLL 是哪一種 請說詳細一點,才能夠幫你啊
perry722
一般會員


發表:27
回覆:11
積分:7
註冊:2004-05-05

發送簡訊給我
#3 引用回覆 回覆 發表時間:2005-03-24 11:01:31 IP:202.175.xxx.xxx 未訂閱
謝謝你的回覆,那個dll是api的. 1437
------
1437
Vicen
高階會員


發表:13
回覆:145
積分:151
註冊:2005-03-14

發送簡訊給我
#4 引用回覆 回覆 發表時間:2005-03-24 11:06:34 IP:221.226.xxx.xxx 未訂閱
VB编写的DLL称为ActiveX DLL,并非真正意义上的DLL,使用前你必须将它注册一下。 方法: RegSvr32 DLL文件路径名称 用RegSvr32 /u DLL文件路径名称 可以取消注册。 建议你用这种方法,就是用菜单“使用Project|Import Type Library”导入你的DLL,DELPHI会为你自动建立一个相关的单元,用这个单元你就可以直接用VB DLL 了。 你也可以用CreateObject动态建立对象,这种方法灵活一些,DELPHI安装目录下“Demos\ActiveX\OleAuto\AutoCtrl”里有类似的示例程序,原理是一样的。 發表人 - vicen 於 2005/03/24 11:35:44 發表人 - vicen 於 2005/03/24 11:39:44
perry722
一般會員


發表:27
回覆:11
積分:7
註冊:2004-05-05

發送簡訊給我
#5 引用回覆 回覆 發表時間:2005-03-24 11:18:23 IP:202.175.xxx.xxx 未訂閱
vicen你好,我剛才試過你的方法,在Project|Import Type Library”?入DLL, 但出現error, 內容是載入類型程序庫/DLL時發生錯誤, 這是什麼原因呢? 1437
------
1437
Vicen
高階會員


發表:13
回覆:145
積分:151
註冊:2005-03-14

發送簡訊給我
#6 引用回覆 回覆 發表時間:2005-03-24 11:32:00 IP:221.226.xxx.xxx 未訂閱
什么错误,错误内容可以发送上来吗? 另外你有没有先对DLL进行注册
perry722
一般會員


發表:27
回覆:11
積分:7
註冊:2004-05-05

發送簡訊給我
#7 引用回覆 回覆 發表時間:2005-03-24 11:46:07 IP:202.175.xxx.xxx 未訂閱
注冊時發生錯誤, 錯誤訊息如下圖,  這是什麼原因呢?還有,呼叫dll時一定要將其注冊後才可以使用的嗎? 1437
------
1437
Vicen
高階會員


發表:13
回覆:145
積分:151
註冊:2005-03-14

發送簡訊給我
#8 引用回覆 回覆 發表時間:2005-03-24 12:20:03 IP:221.226.xxx.xxx 未訂閱
下面是自动注册DLL或OCX的函数。    
unit UAutoRegActiveX;    interface    uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, ComObj; //加入ComObj单元    type
  TAutoRegActiveXFrm = class(TForm)
    procedure FormCreate(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  protected
    { Public declarations }
    procedure CheckException(Sender: TObject; EAbort: Exception);
  end;    var
  AutoRegActiveXFrm: TAutoRegActiveXFrm;    implementation    {$R *.dfm}    {-------------------------------------------------
标准ActiveX控件中,有两个函数DLLRegisterServer 、DLLUnRegisterServer可调用,其中函数用于注册控件,用于卸载控件。我们可用LoadLibrary装载DLL/OCX文件,用GetProcAddress获取DLLRegisterServer和DLLUnRegisterServer两个函数的指针,然后再直接运行这两个函数即可实现注册和卸载ActiveX控件的操作,从而代替Windows系统的RegSvr32.exe实现ActiveX控件的注册和卸载。
--------------------------------------------------}
{-------------------------------------------------
参数说明:
sOleFileName 一个DLL或OCX文件名;
OleAction 表示注册操作类型:1表示注册,0表示卸载
返回值:True表示操作执行成功,False表示操作执行失败
--------------------------------------------------}
function OLERegister(sOleFileName: String; OleAction: Byte):Boolean;
const
  RegisterOle = 1; //注册
  UnRegisterOle = 0; //卸载
type
  TOleRegisterFunction = function: HResult; //注册或卸载函数原型
var
  hLibraryHandle: THandle; //由LoadLibray返回的DLL或OCX句柄
  hFunctionAddress: TFarProc; //DLL或OCX中的函数句柄,由GetProAddress返回
  RegFunction: TOleRegisterFunction; //注册或卸载函数指针
begin
  Result := False;
  //打开文件,返回DLL或OCX句柄
  hLibraryhandle := LoadLibrary(PChar(SOleFileName));
  if (hLibraryHandle > 0) then //DLLakg OCX句柄正确
  try
    //返回注册或卸载函数指针
    if (OleAction = RegisterOle) then  //返回注册函数指针
      hFunctionAddress := GetProcAddress(hLibraryhandle,PChar('DLLRegisterServer'))
    else //返回卸载函数指针
      hFunctionAddress := GetProcAddress(hLibraryhandle,PChar('DLLUnRegisterServer'));
    if (hFunctionAddress <> nil) then //判断注册或卸载函数是否存在
    begin
      RegFunction := TOleRegisterFunction(hFunctionAddress); //获取操作函数的指针
      if RegFunction >=0 then  //执行注册或卸载操作,返回值>=0表示执行成功
        Result := True;
    end;
  finally
    FreeLibrary(hLibraryHandle); //关闭已打开的文件
  end;
end;    { TAutoRegActiveXFrm }    procedure TAutoRegActiveXFrm.CheckException(Sender: TObject;
  EAbort: Exception);
begin
  if EAbort is EOleSysError then
  begin
    if HResult(EOleSysError(EAbort).ErrorCode) = REGDB_E_CLASSNOTREG then
      OleRegister('D:\Flash.ocx',1);
  end
  else
    Application.ShowException(EAbort);
end;
//将CheckException方法赋值给系统Application变量,在主Form的OnCreate事件中。
procedure TAutoRegActiveXFrm.FormCreate(Sender: TObject);
var
  DemoOcx: Variant; //变量声明
begin
  Application.OnException := CheckException;
  //是否产生类名称字符串错误
  try
    DemoOcx := CreateOleObject('Demo.Demo');
  except
    on EAbort:EOleSysError do
    if HResult(EAbort.ErrorCode) = CO_E_CLASSSTRING then
    begin
      if OleRegister('D:\Flash.ocx',1) then
        DemoOcx := CreateOleObject('Demo.Demo')
      else
      begin
        Application.MessageBox('控件注册失败,程序将无法正常运行',PChar('注册控件'),MB_OK MB_ICONERROR);
        Application.Terminate;
      end;
    end;
  end;
end;    end.
出现上面情况,是因为你的DLL本身的问题,没有入口。
wyndog
資深會員


發表:7
回覆:362
積分:348
註冊:2004-10-12

發送簡訊給我
#9 引用回覆 回覆 發表時間:2005-03-24 12:22:17 IP:60.248.xxx.xxx 未訂閱
引言: 謝謝你的回覆,那個dll是api的.
在 interface 裡加上
function 函數名(參數型態): 傳回值; stdcall;
  or
procedure 函數名(參數型態); stdcall;
在 implementation 裡加上
function 函數名; external 'iguard.dll' name '函數名';
or
procedure 函數名; external 'iguard.dll' name '函數名';
Vicen
高階會員


發表:13
回覆:145
積分:151
註冊:2005-03-14

發送簡訊給我
#10 引用回覆 回覆 發表時間:2005-03-24 12:34:18 IP:221.226.xxx.xxx 未訂閱
VB能写标准DLL吗,应该是ActiveX DLL,所以reptile兄的标准DLL调用方法应该不行的吧~
wyndog
資深會員


發表:7
回覆:362
積分:348
註冊:2004-10-12

發送簡訊給我
#11 引用回覆 回覆 發表時間:2005-03-24 13:04:35 IP:60.248.xxx.xxx 未訂閱
引言: VB能写标准DLL吗,应该是ActiveX DLL,所以reptile兄的标准DLL调用方法应该不行的吧~
其實我沒用過 VB 寫 DLL,所以我也不曉得行不行 :p
系統時間:2024-06-16 16:28:44
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!