dll窗体及数据调用-delphi DLL数据及窗体调用

问题描述

delphi DLL数据及窗体调用

DLL工程文件代码:

library DLLUSERS;
uses
  Windows,
  ADODB,
  Dialogs,
  Forms,
  SysUtils,
  Classes,
  U_DataModule in 'U_DataModule.pas' {DataModule1: TDataModule},
  U_Users in 'U_Users.pas' {Frm_Users},
  U_Initialize in 'U_Initialize.pas';
{$R *.res}
function GetForm(ClassName: PChar; DM: TDataModule1): TFormClass; stdcall;
begin
  DataModule1 := DM;
  Result:=TFormClass(FindClass(ClassName));
end;

procedure InitDLL(DM: TDataModule1); stdcall;
begin
  DataModule1:=DM;
end;

exports
  GetForm,InitDLL,SetUseName;
begin
end.

DLL公共单元代码:

unit U_Initialize;
{DLL公共单元UNIT}
interface

  function GetUseName: PChar; stdcall;
  procedure SetUseName(SName: PChar); stdcall;

var
  StrName: PChar;

implementation

uses
  U_DataModule, ActiveX;

function GetUseName: PChar; stdcall;
begin
  Result:=StrName;
end;

procedure SetUseName(SName: PChar); stdcall;
begin
  StrName:=SName;
end;

initialization
  CoInitialize(nil);
  DataModule1 := TDataModule1.Create(nil);
finalization
  DataModule1.Free;
  CoUninitialize;

end.

DLL数据模块代码:

 unit U_DataModule;
{数据模块}
interface

uses
  SysUtils, Classes, DB, ADODB;

type
  TDataModule1 = class(TDataModule)
    ADOCNT: TADOConnection;
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  DataModule1: TDataModule1;

implementation

{$R *.dfm}

end.

DLL内部窗体代码:

 unit U_Users;
{DLL内部窗体}
interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, DBGridEhGrouping, ComCtrls, GridsEh, DBGridEh, ExtCtrls,
  RzPanel, Menus, ADODB, DB, EhlibCDS, EhlibADO, Comobj, DBGridEhImpExp,
  U_DataModule;

type
  TFrm_Users = class(TForm)
    MainMenu1: TMainMenu;
    mmAdd: TMenuItem;
    mmEdit: TMenuItem;
    mmDelete: TMenuItem;
    mmRight: TMenuItem;
    mmFind: TMenuItem;
    mmDataOut: TMenuItem;
    mmClose: TMenuItem;
    RzGroupBox1: TRzGroupBox;
    DBGridEhUsers: TDBGridEh;
    StatusBar1: TStatusBar;
    SaveDialog1: TSaveDialog;
    procedure FormCreate(Sender: TObject);
    procedure FormShow(Sender: TObject);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
  private
    { Private declarations }
  public
    ADOUsers,ADODelete:TADOQuery;
    DSUsers: TDataSource;
    { Public declarations }
  end;

var
  Frm_Users: TFrm_Users;

implementation

uses
  U_Initialize;

{$R *.dfm}

procedure TFrm_Users.FormCreate(Sender: TObject);
begin
  Font.Name:='Arial';
  ADOUsers:=TADOQuery.Create(nil);
  ADODelete:=TADOQuery.Create(nil);
  DSUsers:=TDataSource.Create(nil);
  ADOUsers.Connection:=DataModule1.ADOCNT;
  ADODelete.Connection:=DataModule1.ADOCNT;
  //设置文件类型列表和默认文件类型
  SaveDialog1.Filter:='Text files (*.txt)|*.TXT|Comma separated values (*.csv)|*.CSV|HTML file (*.htm)|*.HTM|Rich Text Format (*.rtf)|*.RTF|Microsoft Excel Workbook (*.xls)|*.XLS';
  SaveDialog1.FilterIndex:=0;
end;

procedure TFrm_Users.FormShow(Sender: TObject);
begin
  StrName:=GetUseName;
  with  ADOUsers  do
  begin
    Close;
    SQL.Clear;
    if String(StrName)='alsaby' then
    SQL.Add('select a.*,b.Person_Name,c.Partment_Name from t_User a '+
            'left join t_Person b on a.User_PersonId=b.Person_Id '+
            'left join t_Partment c on a.User_PartmentId=c.Partment_Id '+
            'order by a.User_Name') else
    if String(StrName)='admin' then
    SQL.Add('select a.*,b.Person_Name,c.Partment_Name from t_User a '+
            'left join t_Person b on a.User_PersonId=b.Person_Id '+
            'left join t_Partment c on a.User_PartmentId=c.Partment_Id '+
            'where a.User_Name<>''alsaby'' order by a.User_Name') else
    SQL.Add('select a.*,b.Person_Name,c.Partment_Name from t_User a '+
            'left join t_Person b on a.User_PersonId=b.Person_Id '+
            'left join t_Partment c on a.User_PartmentId=c.Partment_Id '+
            'where a.User_Name<>''alsaby'' and a.User_Name<>''admin'' order by a.User_Name');
    Open;
  end;
  DSUsers.DataSet:=ADOUsers;
  DBGridEhUsers.DataSource:=DSUsers;
  StatusBar1.Panels[1].Text:=IntToStr(ADOUsers.RecordCount) +' 条数据。';
end;

procedure TFrm_Users.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  ADOUsers.Close;
  ADOUsers.Destroy;
  ADODelete.Close;
  ADODelete.Destroy;
  DSUsers.Destroy;
  Action:=caFree;
end;

initialization
  RegisterClass(TFrm_Users);
finalization
  UnRegisterClass(TFrm_Users);
end.

主程序调用代码:

 unit U_Main;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, Menus, ImgList, ComCtrls, ADODB, DB, jpeg, ExtCtrls, RzPanel,
  RzSplit, RzTreeVw, U_DataModule;

type
  TInitDLL = procedure(DM: TFrm_DataModule); stdcall;
  TSetUseName = procedure(SName: PChar); stdcall;
  TGetForm = function(ClassName: PChar; DM: TFrm_DataModule): TFormClass; stdcall;
  TFrm_Main = class(TForm)
    MainMenu1: TMainMenu;
    mmSysFlies: TMenuItem;
    mmUserChange: TMenuItem;
    N2: TMenuItem;
    mmExit: TMenuItem;
    N1: TMenuItem;
    mmBakRecover: TMenuItem;
    mmSysUser: TMenuItem;
    N5: TMenuItem;
    StatusBar1: TStatusBar;
    OpenDialog1: TOpenDialog;
    ImageList1: TImageList;
    procedure FormCreate(Sender: TObject);
    procedure mmSysUserClick(Sender: TObject);
  private
    { Private declarations }
  public
    UName: String;
    { Public declarations }
  end;

var
  Frm_Main: TFrm_Main;
implementation

uses
  U_Public;

{$R *.dfm}

procedure TFrm_Main.FormCreate(Sender: TObject);
begin
  Font.Name:='Arial';
  UName:=Frm_DataModule.ADO_User.FieldByName('User_Name').AsString;
end;

procedure TFrm_Main.mmSysUserClick(Sender: TObject);
var
  DLLName: String;
  DLLHandle: THandle;
  FarProc: TFarProc;
  Form: TForm;
  SetUseName: TSetUseName;
  GetForm: TGetForm;
  InitDLL: TInitDLL;
begin
  GetDir(0,DLLName);
  DLLName := DLLName + 'DLLUSERS.dll';
  DLLHandle:= SafeLoadLibrary(DLLName);
  if DLLHandle > 0 then
    Try
      FarProc := GetProcAddress(DLLHandle, 'InitDLL');
      if FarProc<>nil then
      begin
        InitDLL := TInitDLL(FarProc);
        InitDLL(Frm_DataModule);
      end;

      FarProc := GetProcAddress(DLLHandle, 'SetUseName');
      if FarProc<>nil then
      begin
        SetUseName := TSetUseName(FarProc);
        SetUseName(PChar(Trim(UName)));
      end;

      FarProc := GetProcAddress(DLLHandle, 'GetForm');
      if FarProc<>nil then
      begin
        GetForm := TGetForm(FarProc);
        Form := GetForm('TFrm_Users', Frm_DataModule).Create(nil);
        Form.ShowModal;
        FreeAndNil(Form);
      end;
    Finally
      FreeLibrary(DLLHandle);
    End
  else
  ShowMessage(DLLName+'文件不存在!');
end;

end.

以上在运行程序时没有错误,数据也正常显示,但是关闭调用的DLL内部窗体后,再次通过主程序调用就出现了Read of Address 00000008错误,请高手指点这是咋回事?

解决方案

function GetForm(ClassName: PChar; DM: TDataModule1): TFormClass; stdcall;
begin
DataModule1 := DM;
Result:=TFormClass(FindClass(ClassName));
end;

procedure InitDLL(DM: TDataModule1); stdcall;
begin
DataModule1:=DM;
end;

传递了对象,是不可取的。必成传递TADOConnection的连接字符,就可以了。

解决方案二:

改成传递TADOConnection的连接字符 ConnectionString,就可以了。

解决方案三:

delphi 调用dll窗体
delphi动态调用dll窗体
调用DLL窗体-Delphi实例

解决方案四:

回复 Robot-D
我看了你的实例,如果ADOCONNECTION创建在数据模块又怎么处理呢?

解决方案五:

通过构造函数或者变量把adoconnection传过来。

解决方案六:

首先你写的DLL,导出函数中居然传递了Delphi对象,如果传递对象,请带包编译,否则会出现问题,如果不想带包,可以使用接口代替对象传递

时间: 2024-08-03 08:03:58

dll窗体及数据调用-delphi DLL数据及窗体调用的相关文章

调用Delphi Dll 出现无法封送处理return value错误

问题描述 如题,以下是代码部分[DllImport("ftpdll.dll",EntryPoint="FtpServerDir",CharSet=CharSet.Auto,CallingConvention=CallingConvention.StdCall)]protectedstaticexternbyte[]FtpServerDir(IntPtrTHandle,byte[]FTPServer,byte[]DirName);///<summary>/

vb.net-Vb.net 调用C++ dll遇到的问题

问题描述 Vb.net 调用C++ dll遇到的问题 头文件里的方法时这样的 /**@brief 创建一个会议实例,每次调用都会获得一个新的会议实例 *@param[in] nCompentSet 需要加载的组件,参考定义 *CONF_PARAM_COMPONENT_AS = 0x001L, *CONF_PARAM_COMPONENT_DS = 0x002L, *CONF_PARAM_COMPONENT_PL = 0x004L, *CONF_PARAM_COMPONENT_CB = 0x008L

.net Winform程序调用delphi编写的dll出错,求救!!

问题描述 winform调用delphi的dll,delphi里面的代码是连接远程服务器,发送过来数据,并在dll里处理接收.我在.net用委托调用delphi的接口方法,获取到了delphi传过来的实时数据,但是在获取到6分钟的时候就不获取了,连接都正常,也不报错,找不到原因,求高手解决!!Winform代码:.net声明调用dll:处理回来数据的方法,目前什么都不做:delphi接口代码:入口:触发事件调用的方法:处理数据方法:声明的委托:现在已经将delphi的代码封装成dll,但是.ne

MSsql 增删改某个表时,用触发器调用外部DLL通知外部窗体程序

问题描述 数据库修改记录已经可以触发并顺利调用这个DLL了,但是怎么才能在调用的DLL里给主窗体程序传送数据呢?比如把消息显示在主窗体的文本框上或者在DLL里调用主窗体的方法?//////////////////////////////////////触发器调用的DLLusingSystem;usingSystem.Data;usingSystem.Data.SqlClient;usingMicrosoft.SqlServer.Server;namespaceSQLTrigger{publicp

delphi-求救!!! 调用一个DLL文件的函数,提供的调用方法好像是Delphi,VB怎么调用!

问题描述 求救!!! 调用一个DLL文件的函数,提供的调用方法好像是Delphi,VB怎么调用! 提供的调用方法如下 3.2 封装模式 接口动态库的文件名为nxmi.dll,HIS直接调用nxmi.dll, 调用之前请先安装读卡环境,安装程序为inst.exe. 3.3 调用方法 对外提供的接口函数: Procedure invoke(params :PChar; result : PChar) ; 我现在在VB中写的如下: 在模块下定义 Public Declare Function invo

com-C++ 如何调用Delphi的dll文件中的COM方法

问题描述 C++ 如何调用Delphi的dll文件中的COM方法 请问 C++ 如何 调用 Delphi 的dll文件中的COM方法 解决方案 只要是COM就遵守COM的规范,Delphi写出来的COM和其他语言写出来的COM用法是一样的

asp.net webservice调用Delphi的dll

问题描述 asp.net webservice调用Delphi的dll asp.net webservice调用Delphi的dll,执行方法Init(连接Oracle数据库),报错连接超时. 建立个winform程序,调用Init函数可通过,但webservice就是不行. 我是发布在服务器server 2003 32位, IIS发布,发程序发布的文件扔到IIS根目录,dll文件在bin目录下. 调用的这个dll文件又调用了另一个dll,2个dll文件都扔到bin目录下了.不知道是什么原因,w

winform-急,求大神帮帮忙,关于C#调用delphi的dll文件抛错问题

问题描述 急,求大神帮帮忙,关于C#调用delphi的dll文件抛错问题 [DllImport(_fileDll EntryPoint = ""JX102R_Read_Card"" CharSet = CharSet.Ansi CallingConvention = CallingConvention.StdCall)] public static extern int JX102R_Read_Card(ref int ReaderNo ref StringBuil

delphi-替换Delphi中调用的dll

问题描述 替换Delphi中调用的dll 在一段Delphi编写的dll中调用了另外一个一个A.dll,现在想将这个A.dll替换为自己写的B.dll.只是知道A大概的功能,B是自己写的,中间需要注意些什么? 解决方案 用depend看下导出表,有什么函数名,函数序数,然后用ollydbg之类的工具调试,看看参数是怎么传的,通过堆栈可以分析出来. 然后自己照着写. 解决方案二: Delphi 调用VC的DLLDelphi调用DLL中的接口Delphi调用DLL中的接口