【问题标题】:Delphi: Resource not found error?Delphi:找不到资源错误?
【发布时间】:2011-12-27 21:40:01
【问题描述】:

我正在尝试使用 BPL 在 delphi2010 中制作模块化应用程序。 问题是当我尝试在 BPL 中创建类时,我收到此错误消息。

我没有对资源(RES文件)做任何操作!

Procedure TControllerMain.Btn1OnClick(Sender: TObject);
type
  TInitProcedure = function: TModuleBaseClass; stdcall;
  TModuleBaseClass= class of TModuleBase;
var
  h: HMODULE;
  proc: TInitProcedure;
  vClass: TModuleBaseClass;
begin
  h := LoadPackage('test.bpl');
  @proc := GetProcAddress(h, 'InitializePlugin');
  vClass := proc();
  vClass.Create(nil);  // error here
  UnloadPackage(h);
end;

dll代码

TModuleBase 是一个 TCustomPanel

type
  TVLCVideo = class(TModuleBase)
  private
   ...
  public
   ...
  end;
function InitializePlugin: TModuleBaseClass; stdcall;


implementation
function InitializePlugin: TModuleBaseClass;
begin
  Result := TVLCVideo;
end;


exports
  InitializePlugin;

end.

【问题讨论】:

  • 在 DFM 流式传输期间会发生这种错误,但前提是 TModuleBase 源自 TFormTFrameTDataModule,而不是源自 TCustomPanel
  • 好吧,你能告诉我有没有办法在 dll 中使用组件?我不想创建 ActiveX 组件
  • 如果InitializePlugin()返回的是实例化对象而不是类类型,你是否也有同样的问题?发生错误时调用堆栈是什么样的?
  • 谢谢 Remy,我用接口解决了这个问题
  • @relative,您能否将解决方案粘贴为答案并自己接受?它可能对未来遇到同样问题的访问者有所帮助。

标签: delphi dll


【解决方案1】:

解决办法:

我使用 TCustomPanel 作为 TModulBase 的祖先,但我发现了问题,Remy 是对的。然后我删除了祖先类以替换为接口,并且我所有的另一个插件都必须使用相同的接口(如果您将这种方式与普通的 dll 项目一起使用,您将得到一个不同的错误!我尝试过 :( 你必须使用它使用 bpl(bpl 也是一个 dll))

PIModuleBase = ^IModulBase;

IModulBase = interface 
   ...
end;

此按钮单击只是一个示例,您必须创建一个模块管理器类

Procedure TControllerMain.Btn1OnClick(Sender: TObject);
type
  TInitProcedure = function: PIModuleBase; stdcall;

var
  h: HMODULE;
  proc: TInitProcedure;
  vClass: PIModuleBase;
begin
  h := LoadPackage('test.bpl');
  @proc := GetProcAddress(h, 'InitializePlugin');
  vClass := proc();
  vClass^.setParent(form1);
  vClass^.setPosition(0,0,100,100);
  vClass^.play(PChar('url of media'));  
  //UnloadPackage(h);
end;



type
  TVLCVideo = class(TCustomPanel, IModulBase)
  private
   ...
  public
   ...
  end;
function InitializePlugin: PIModuleBase; stdcall;


implementation
function InitializePlugin: PIModuleBase;
var
 v : TVLCVideo;
begin
  v := TVLCVideo.Create(nil);
  Result := IModuleBase(v);
end;


exports
  InitializePlugin;

end.

重要的事情:

您不能直接将接口库文件导入模块包文件或在主应用程序项目中!您必须为接口和共享库文件创建一个新的 bpl 项目,并且您需要将它们放在您的模块包中,例如 vlc、rtl。

而且你需要用这个接口包构建主应用

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-11-24
    • 2012-03-06
    • 2018-07-18
    • 2015-11-24
    • 2018-08-18
    • 1970-01-01
    相关资源
    最近更新 更多