技术标签: 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.
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.
安装所需依赖$ 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环境,并将其与SpringMVC进行整合,现在学习如何进行界面的定义,以及界面元素的操作。效果图界面操作图原始界面 调整后的界面(删除了flush,表单元素等) 该界面的皮肤是bootstrap的皮肤事件操作图获取界面上保存按钮点击事件效果用js操作ckeditor控制的textarea自定义界面ckeditor默认使用moono皮肤
Python自然语言处理 Steven Bird 2014年第一版 第二章课后习题
参考: 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)的核心功能,...
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++语言中string不提供去除空格的库函数。但是,C++ string也提供很强大的功能,实现trim这种功能。#include #include std::string& trim(std::string &s) { if (s.empty()) { return s; } s.erase(0,s.find_first_
title: swoole 在 swoft 中的应用swoft 官网: https://www.swoft.org/swoft 源码解读: http://naotu.baidu.com/file/814e81c9781b733e04218ac7a0494e2a?token=f009094c71a791c5号外号外, 欢迎大家 star, 我们开发组定了一个 star 1000+ 就线下聚一次...
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()函数是取某个月最后一天的日期。例如:SELECT LAST_DAY('2019-04-01') 取2019年4月的最后一天的日期。因为4月只有30天,所以2019年4月的最后一天是2019-04-30。...
题目地址:点击打开链接思路:因为数据量比较小,直接搜索枚举放乘号的位置就行。注意枚举到最后一位数字后别忘了记录下来。代码:#include#include#includeusing namespace std;typedef long long ll;ll rec[10], ans;int num[25], n, k;bool book[25]
蓝桥杯VIP试题 之 基础练习 数的读法 - JAVA
使用CSVPrinter类,apache CSVPrinter类官方API文档:官网API样例:1.引入POM依赖 <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-csv<...