Dll学习三_Dll 相互间以及主程序间的数据共享——测试未通过,应该用内存映射_dll之间认识同一个结构体_胡伟峰的博客-程序员秘密

技术标签: Delphi类  

测试环境:XP,DELPHI XE

验证通过结构:主程序+一个Dll窗体

共享方式原理:通过主程序与各Dll定义相同的参数结构体,由主程序实例化该结构体,对于各Dll间的共享,通过传主程序实例化的结构体指针达到各Dll与主程序相互间的数据共享。且Dll释放不影响主程序实例化结构体时获得的内存空间


主程序代码:

unit Main_Unit;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
  TPara = record
    ADOConnStr: String;
  end;
  TCreateFrm = procedure(AppHnd: THandle; APar: TPara); stdcall;		//此处传递主程序实例化后的参数结构体
  TCreateSubFrm = procedure(AppHnd: THandle); stdcall;
  TDropFrm = procedure; stdcall;
  TFrm_Main = class(TForm)
    Btn_1: TButton;
    Btn_2: TButton;
    Btn_3: TButton;
    Btn_4: TButton;
    Btn_5: TButton;
    Btn_6: TButton;
    Btn_7: TButton;    procedure Btn_1Click(Sender: TObject);
    procedure Btn_2Click(Sender: TObject);
    procedure Btn_3Click(Sender: TObject);
    procedure Btn_4Click(Sender: TObject);
    procedure Btn_5Click(Sender: TObject);
    procedure Btn_6Click(Sender: TObject);
    procedure Btn_7Click(Sender: TObject);
  private
    LibHandle: THandle;
    FormRef: LongInt;
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Frm_Main: TFrm_Main;
  APara: TPara;

implementation

{$R *.dfm}

procedure TFrm_Main.Btn_1Click(Sender: TObject);
begin
  if LibHandle = 0 then
  begin
    LibHandle := SafeLoadLibrary('SubMain.dll');
    if LibHandle = 0 then
      raise Exception.Create('Not Found Dll File')
    else
      ShowMessage('Dll Loaded');
  end;
end;

procedure TFrm_Main.Btn_2Click(Sender: TObject);
begin
  if LibHandle > 0 then
  begin
    FreeLibrary(LibHandle);
    LibHandle := 0;
    ShowMessage('Dll UnLoaded');
  end;
end;

procedure TFrm_Main.Btn_3Click(Sender: TObject);
var
  CreateFrm: TCreateFrm;
begin
  if LibHandle = 0 then
    raise Exception.Create('Place Load Dll File First');

  @CreateFrm := GetProcAddress(LibHandle,PChar('CreateFrm'));
  if @CreateFrm = nil then
    raise Exception.Create('Function Error');

  APara.ADOConnStr := 'Provider=SQLOLEDB.1;Password=*****;Persist Security Info=True;User ID=sa;Initial Catalog=test;Data Source=127.0.0.1';	//结构体赋值
  CreateFrm(Application.Handle,APara);
end;

procedure TFrm_Main.Btn_4Click(Sender: TObject);
var
  DropFrm: TDropFrm;
begin
  @DropFrm := GetProcAddress(LibHandle,PChar('DropFrm'));
  if @DropFrm = nil then
    raise Exception.Create('Function Error');

  DropFrm;
end;

procedure TFrm_Main.Btn_5Click(Sender: TObject);
var
  CreateSubFrm: TCreateSubFrm;
begin
  if LibHandle = 0 then
    raise Exception.Create('Place Load Dll File First');

  @CreateSubFrm := GetProcAddress(LibHandle,PChar('CreateSubFrm'));
  if @CreateSubFrm = nil then
    raise Exception.Create('Function Error');

  CreateSubFrm(Application.Handle);
end;

procedure TFrm_Main.Btn_7Click(Sender: TObject);
begin
  ShowMessage(APara.ADOConnStr);			//用来释放Dll后,验证结构体内存块是否同步被释放
end;

end.

Dll引用代码:

unit SubMain_Unit;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, DB, FyDataConn_Unit, ActiveX,
  ADODB, StdCtrls, cxGraphics, cxControls, cxLookAndFeels,
  cxLookAndFeelPainters, cxStyles, dxSkinsCore, dxSkinBlueprint,
  dxSkinDevExpressDarkStyle, dxSkinDevExpressStyle, dxSkinHighContrast,
  dxSkinSevenClassic, dxSkinSharpPlus, dxSkinStardust, dxSkinTheAsphaltWorld,
  dxSkinVS2010, dxSkinWhiteprint, dxSkinscxPCPainter, cxCustomData, cxFilter,
  cxData, cxDataStorage, cxEdit, cxNavigator, cxDBData, cxGridLevel, cxClasses,
  cxGridCustomView, cxGridCustomTableView, cxGridTableView, cxGridDBTableView,
  cxGrid, Grids, DBGrids,dxCore;

type
  TPara = record				//与主程序定义一个一样的结构体
    ADOConnStr: String;
  end;
  TPPara = ^TPara;				//定义该结构体的指针结构
  TFrm_SubMain = class(TForm)
    Btn_1: TButton;
    GTV_1: TcxGridDBTableView;
    GL_1: TcxGridLevel;
    Grd_1: TcxGrid;
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
    procedure FormDestroy(Sender: TObject);
    procedure Btn_1Click(Sender: TObject);
    procedure FormCreate(Sender: TObject);
  private
    DSet: TADODataSet;
    DS: TDataSource;
    Conn: TADOConnection;
    { Private declarations }
  public
    { Public declarations }
  end;
  procedure CreateFrm(AppHnd: THandle; APar: TPara);export;stdcall;
  procedure DropFrm; export;stdcall;

var
  Frm_SubMain: TFrm_SubMain;
  LocPara: TPara;
  PPara: TPPara;

implementation

{$R *.dfm}
procedure CreateFrm(AppHnd: THandle; APar: TPara);
begin
  Application.Handle := AppHnd;
  PPara := @APar;		//直接
  if not Assigned(Frm_SubMain) then
    Frm_SubMain := TFrm_SubMain.Create(Application);

  Frm_SubMain.Show;
end;

procedure DropFrm;
begin
  if Frm_SubMain <> nil then
    FreeAndNil(Frm_SubMain);
end;
procedure TFrm_SubMain.Btn_1Click(Sender: TObject);
var
  SQL: String;
begin
  DSet.Connection := Conn;
  DS.DataSet := DSet;
  SQL := 'Select * From Cg_CgDanSub';
  dbOpen(SQL,DSet);       //自定义函数,用于打开数据集
  GTV_1.DataController.DataSource := DS;
  (GTV_1.DataController as IcxCustomGridDataController).DeleteAllItems;           //清除cxGrid列
  (GTV_1.DataController as IcxCustomGridDataController).CreateAllItems(False);    //添加cxGrid列

end;

procedure TFrm_SubMain.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  Action := caFree;
end;

procedure TFrm_SubMain.FormCreate(Sender: TObject);
begin
  Conn := TADOConnection.Create(Application);
  Conn.LoginPrompt := False;
  Conn.ConnectionString := PPara.ADOConnStr;
  //Conn.ConnectionString := 'Provider=SQLOLEDB.1;Password=fydesign;Persist Security Info=True;User ID=sa;Initial Catalog=test;Data Source=127.0.0.1';
  Conn.Connected := True;
  DSet := TADODataSet.Create(Application);
  DS := TDataSource.Create(Application);
end;

procedure TFrm_SubMain.FormDestroy(Sender: TObject);
begin
  DSet.Free;
  DS.Free;
  FreeAndNil(Conn);
  Frm_SubMain := nil;
end;
initialization
  dxInitialize;
finalization
  dxFinalize;
end.


版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/jupt1/article/details/17006735

智能推荐

DragonBone和Spine互相转化指令实现_阿迪不想上班的博客-程序员秘密

安装所需依赖$ npm install dragonbones-tools --global使用方法将当面目录下所有的 Spine JSON 格式文件转换为龙骨 JSON 格式文件。$ 2db -t spine将当面目录下所有的 Live2d JSON 格式文件转换为龙骨 JSON 格式文件。$ 2db -t live2d将当面目录下所有的龙骨 JSON 格式文件转换为最新的龙骨 JSON 格式文件。$ db2 -t new将当面目录下所有的龙骨 JSON 格式文件转换为 Spin

CKEditor与CKFinder学习--自定义界面及按钮事件捕获_GW_Cheng的博客-程序员秘密

上一篇博客写了如何搭建CKEditor与CKFinder环境,并将其与SpringMVC进行整合,现在学习如何进行界面的定义,以及界面元素的操作。效果图界面操作图原始界面 调整后的界面(删除了flush,表单元素等) 该界面的皮肤是bootstrap的皮肤事件操作图获取界面上保存按钮点击事件效果用js操作ckeditor控制的textarea自定义界面ckeditor默认使用moono皮肤

PythonNLP学习进阶:第二章练习题(Python自然语言处理)_txlCandy的博客-程序员秘密

Python自然语言处理 Steven Bird 2014年第一版 第二章课后习题

Android-低功耗蓝牙(BLE)-客户端(主机/中心设备)和服务端(从机/外围设备)_windows下ble蓝牙外围设备开发_lioil.win的博客-程序员秘密

参考: https://developer.android.com/guide/topics/connectivity/bluetooth-le http://a1anwang.com/post-47.html一.Android 低功耗蓝牙(BLE)的API简介从Android 4.3(API 18)才支持低功耗蓝牙(Bluetooth Low Energy, BLE)的核心功能,...

Oracle启动停止命令 (收藏)_oracle停止命令_如果这都不算爱的博客-程序员秘密

1、启动数据库:[email protected]:~> sqlplus /nolog SQL*Plus: Release 9.2.0.4.0 - Production on Fri Jan 20 02:29:37 2006 Copyright (c) 1982, 2002, Oracle Corporation. All rights reserved. SQL> conne

[C++]去除sting首尾空格_c++怎么去除末尾的空格_子建莫敌的博客-程序员秘密

标准C++语言中string不提供去除空格的库函数。但是,C++ string也提供很强大的功能,实现trim这种功能。#include #include std::string& trim(std::string &s) { if (s.empty()) { return s; } s.erase(0,s.find_first_

随便推点

swoole 在 swoft 中的应用_swoft swoole_宋民咕的博客-程序员秘密

title: swoole 在 swoft 中的应用swoft 官网: https://www.swoft.org/swoft 源码解读: http://naotu.baidu.com/file/814e81c9781b733e04218ac7a0494e2a?token=f009094c71a791c5号外号外, 欢迎大家 star, 我们开发组定了一个 star 1000+ 就线下聚一次...

UVALive X-Plosives(并查集+略坑的输入)_并查集 uvalive4497_拔剑吧炮姐是我的的博客-程序员秘密

1.此题的题意非常简单,但是题目可能较难读懂2.输入输出是坑,输入-1后再输入eof文件才结束,且3.此题的代码如下:#include #include #include #include #include #include using namespace std;int fat[100100];int Find(int a){    while

mysql LAST_DAY() 函数_常山领主的博客-程序员秘密

mysql中LAST_DAY()函数是取某个月最后一天的日期。例如:SELECT LAST_DAY('2019-04-01') 取2019年4月的最后一天的日期。因为4月只有30天,所以2019年4月的最后一天是2019-04-30。...

qduoj 30 帅气的HYC求乘积(dfs)_cillyb的博客-程序员秘密

题目地址:点击打开链接思路:因为数据量比较小,直接搜索枚举放乘号的位置就行。注意枚举到最后一位数字后别忘了记录下来。代码:#include#include#includeusing namespace std;typedef long long ll;ll rec[10], ans;int num[25], n, k;bool book[25]

java输出csv文件_new csvdatastorefactory()导入那个pom依赖_charlieshawn的博客-程序员秘密

使用CSVPrinter类,apache CSVPrinter类官方API文档:官网API样例:1.引入POM依赖 &lt;dependency&gt; &lt;groupId&gt;org.apache.commons&lt;/groupId&gt; &lt;artifactId&gt;commons-csv&lt...

推荐文章

热门文章

相关标签