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

DLL可以自訂一種型態讓不同的Project使用嗎?

答題得分者是:P.D.
mnsf
初階會員


發表:104
回覆:90
積分:48
註冊:2003-11-25

發送簡訊給我
#1 引用回覆 回覆 發表時間:2015-10-16 09:56:01 IP:1.34.xxx.xxx 訂閱
假設我自訂了一個型態在一個DLL裡面,然後想寫一個function getMytype:Tmytype;,回傳值就是此Tmytype
Type
Tmytype=record
a:integer;
b:double;
c:boolean;
end;

然後,我有兩個project:Project_A,Project_B都可以去呼叫 getMytype,
我有試過,如果在Project_A,Project_B都有宣告Tmytype這一段程式,是沒有問題的
Type
Tmytype=record
a:integer;
b:double;
c:boolean;
end;

但是如果日後Tmytype要新增一個d:string時,就必須三個Project(DLL,Project_A,Project_B)都要改程式,覺得很不聰明
所以想請教,在DLL自訂型態,有可能讓其他Project使用嗎?

P.D.
版主


發表:571
回覆:3885
積分:3672
註冊:2006-10-31

發送簡訊給我
#2 引用回覆 回覆 發表時間:2015-10-16 20:26:22 IP:61.224.xxx.xxx 未訂閱
有幾種做法

1. 宣告一個共用的Memory Block, 讓 dll , a, b 都共同存取這個區域內的變數, 但難度很高, 可能又因為不同的windows作業系統有不同的方式, 我也不會
2. 由 dll 產生一個實質的檔案, 可能是文字檔, 可能是資料庫, 由 a, b 去訵取, 當然該怎麼設計及未來預甶可能增加的變數, 就要靠你自己的智慧來解決了
3. 利用程式後面可以搭參數的方式導入這些變數, 例如 a.exe "var1,var2,var3,var4...) , 再由 b 以param 方式接收

這是我能想的到的, 提供參考!
mnsf
初階會員


發表:104
回覆:90
積分:48
註冊:2003-11-25

發送簡訊給我
#3 引用回覆 回覆 發表時間:2015-10-19 08:49:58 IP:220.128.xxx.xxx 訂閱
感謝版主的回覆
其實我有想過版主說的第二種方法,但是可能會有一堆程式要改.

其實Tmytype是從資料庫讀出來的資料,假設Table Name叫Table1,Table1有上百個欄位
而Project_A,Project_B已有上百支程式已使用Tmytype這種方式去取資料
而每次Table1要加欄位時,都會很麻煩,所以才會發問看看DLL有沒有一勞永逸的方法
leveon
資深會員


發表:30
回覆:386
積分:303
註冊:2012-02-12

發送簡訊給我
#4 引用回覆 回覆 發表時間:2015-10-19 15:01:11 IP:36.226.xxx.xxx 訂閱
不太能理解問題點

將Tmytype 獨立出一個pas擋 多個DLL同時use 該獨立pas 不就好了?

===================引 用 mnsf 文 章===================
感謝版主的回覆
其實我有想過版主說的第二種方法,但是可能會有一堆程式要改.

其實Tmytype是從資料庫讀出來的資料,假設Table Name叫Table1,Table1有上百個欄位
而Project_A,Project_B已有上百支程式已使用Tmytype這種方式去取資料
而每次Table1要加欄位時,都會很麻煩,所以才會發問看看DLL有沒有一勞永逸的方法
mnsf
初階會員


發表:104
回覆:90
積分:48
註冊:2003-11-25

發送簡訊給我
#5 引用回覆 回覆 發表時間:2015-10-20 16:56:34 IP:220.128.xxx.xxx 訂閱
假設Project_A裡面有100支程式,其中一支是Unit1.pas,Unit1.pas裡面有定義Tmytype
而TmyType的資料來源是Database的Table1,Table1有幾個欄位,Tmytype就有幾個成員
Unit1.pas裡面還有一個function叫getMytype,裡面是寫如何在Table1中,取得唯一一筆資料
而Project_A的其他數十支都有使用getMytype
Unit1程式大致是這樣的
unit Unit1;
interface
uses ...
type
Tmytype=record
a:integer;
b:double;
c:boolean;
end;

function getMytype:Tmytype;

implementation

function getMytype:Tmytype;
var tmptype:Tmytype;
begin
//取得取得唯一一筆Table1
result:=tmptype;
end;

另外有一個Project_B,也有一支Unit1,與Project_A的Unit1一模一樣,
而Project_B一樣有數十支程式有使用getMytype
----------------------------------------------------------------------------------------
如果說,今天Table1要新增欄位,我就必須修改Project_A的Unit1及Project_B的Unit1
也就是要改兩份Unit1,而修改的內容是一模一樣的,
所以想把Unit1變成DLL,如果Table1有要新增欄位時,只要修改DLL就可以,不用Project_A,Project_B都要修改
如果Project_A,Project_B及DLL都有定義Tmytype,將getMytype獨立在DLL是OK
但是如此一來,Table1要新增欄位時,Project_A,Project_B及DLL的Tmytype都要跟著改
覺得很不聰明,所以想問Tmytype有沒有什麼方式,只要改DLL的就好了,Projet_A,Project_B不用定義Tmytype,
而是使用DLL裡的Tmytype.
不知道這樣說明有比較詳細嗎?
leveon
資深會員


發表:30
回覆:386
積分:303
註冊:2012-02-12

發送簡訊給我
#6 引用回覆 回覆 發表時間:2015-10-20 17:56:35 IP:36.226.xxx.xxx 訂閱
排版亂跳
編輯記錄
leveon 重新編輯於 2015-10-20 17:59:12, 註解 無‧
leveon 重新編輯於 2015-10-20 18:01:40, 註解 無‧
leveon 重新編輯於 2015-10-20 18:03:32, 註解 無‧
leveon 重新編輯於 2015-10-20 18:03:59, 註解 無‧
leveon
資深會員


發表:30
回覆:386
積分:303
註冊:2012-02-12

發送簡訊給我
#7 引用回覆 回覆 發表時間:2015-10-20 18:04:49 IP:36.226.xxx.xxx 訂閱
所以不是說了
把 Tmytype 獨立出 一個AAA

unit AAA;

interface

uses ...

type

Tmytype=record
a:integer;
b:double;
c:boolean;
end;



之後在每個DLL use AAA 然後再把DLL中 Tmytype宣告全部拿掉
如果Table有新增欄位 只要改AAA.pas中的Tmytype就好?

unit Unit1;

interface

uses AAA;

function getMytype:Tmytype;

implementation


function getMytype:Tmytype;
var tmptype:Tmytype;
begin

//取得取得唯一一筆Table1
result:=tmptype;
end;




這就像你每個Form都有放個 Button
也不用每個Unit 都需要宣告

TButton = class(TCustomButton)

只要use StdCtrls.pas就好

因為TButton 就已經放在StdCtrls.pas裡了



這都是最簡單的方法 為何不這樣做?


不然用{$I filename} {$INCLUDE filename}
編譯指令 把Tmytype 獨立一個文字擋 日後只要改該文字擋就好?
http://docs.embarcadero.com/products/rad_studio/delphiAndcpp2009/HelpUpdate2/EN/html/devcommon/compdirsincludefile_xml.html


另外你講的方法在DLL沒辦法這樣做 因為沒辦法共用變數
用PD說的方法一 sharememory也無法實現 因為Delphi是強型語言
編譯器在編譯時 就要找Tmytype 的宣告了
除非你能改用BPL RTTI
http://stackoverflow.com/questions/23823731/access-all-elements-of-a-record-using-rtti


不了解的問題點就是 簡單的方法不用 為啥要在兜圈子?








===================引 用 mnsf 文 章===================
假設Project_A裡面有100支程式,其中一支是Unit1.pas,Unit1.pas裡面有定義Tmytype
而TmyType的資料來源是Database的Table1,Table1有幾個欄位,Tmytype就有幾個成員
Unit1.pas裡面還有一個function叫getMytype,裡面是寫如何在Table1中,取得唯一一筆資料
而Project_A的其他數十支都有使用getMytype
Unit1程式大致是這樣的
unit Unit1;
interface
uses ...
type
Tmytype=record
a:integer;
b:double;
c:boolean;
end;

function getMytype:Tmytype;

implementation

function getMytype:Tmytype;
var tmptype:Tmytype;
begin
//取得取得唯一一筆Table1
result:=tmptype;
end;

另外有一個Project_B,也有一支Unit1,與Project_A的Unit1一模一樣,
而Project_B一樣有數十支程式有使用getMytype
----------------------------------------------------------------------------------------
如果說,今天Table1要新增欄位,我就必須修改Project_A的Unit1及Project_B的Unit1
也就是要改兩份Unit1,而修改的內容是一模一樣的,
所以想把Unit1變成DLL,如果Table1有要新增欄位時,只要修改DLL就可以,不用Project_A,Project_B都要修改
如果Project_A,Project_B及DLL都有定義Tmytype,將getMytype獨立在DLL是OK
但是如此一來,Table1要新增欄位時,Project_A,Project_B及DLL的Tmytype都要跟著改
覺得很不聰明,所以想問Tmytype有沒有什麼方式,只要改DLL的就好了,Projet_A,Project_B不用定義Tmytype,
而是使用DLL裡的Tmytype.
不知道這樣說明有比較詳細嗎?
mnsf
初階會員


發表:104
回覆:90
積分:48
註冊:2003-11-25

發送簡訊給我
#8 引用回覆 回覆 發表時間:2015-10-21 08:36:15 IP:220.128.xxx.xxx 訂閱
不好意思,不太了解你說的,請教一下AAA要放在哪一個Project裡面?
===================引 用 leveon 文 章===================
所以不是說了
把 Tmytype 獨立出 一個AAA

unit AAA;

interface

uses ...

type

Tmytype=record
a:integer;
b:double;
c:boolean;
end;



之後在每個DLL use AAA 然後再把DLL中 Tmytype宣告全部拿掉
如果Table有新增欄位 只要改AAA.pas中的Tmytype就好?

unit Unit1;

interface

uses AAA;

function getMytype:Tmytype;

implementation


function getMytype:Tmytype;
var tmptype:Tmytype;
begin

//取得取得唯一一筆Table1
result:=tmptype;
end;




這就像你每個Form都有放個 Button
也不用每個Unit 都需要宣告

TButton = class(TCustomButton)

只要use StdCtrls.pas就好

因為TButton 就已經放在StdCtrls.pas裡了



這都是最簡單的方法 為何不這樣做?


不然用{$I filename} {$INCLUDE filename}
編譯指令 把Tmytype 獨立一個文字擋 日後只要改該文字擋就好?
http://docs.embarcadero.com/products/rad_studio/delphiAndcpp2009/HelpUpdate2/EN/html/devcommon/compdirsincludefile_xml.html


另外你講的方法在DLL沒辦法這樣做 因為沒辦法共用變數
用PD說的方法一 sharememory也無法實現 因為Delphi是強型語言
編譯器在編譯時 就要找Tmytype 的宣告了
除非你能改用BPL RTTI
http://stackoverflow.com/questions/23823731/access-all-elements-of-a-record-using-rtti


不了解的問題點就是 簡單的方法不用 為啥要在兜圈子?
leveon
資深會員


發表:30
回覆:386
積分:303
註冊:2012-02-12

發送簡訊給我
#9 引用回覆 回覆 發表時間:2015-10-21 11:02:30 IP:1.164.xxx.xxx 訂閱
加到每一個Project

1.新增一個目錄 將AAA及其他共用的PAS放到該目錄中
2.在每個Project 中的Option ->search path 將該目錄加入


===================引 用 mnsf 文 章===================
不好意思,不太了解你說的,請教一下AAA要放在哪一個Project裡面?
===================引 用 leveon 文 章===================
所以不是說了
把 Tmytype 獨立出 一個AAA

unit AAA;

interface

uses ...

type

Tmytype=record
a:integer;
b:double;
c:boolean;
end;



之後在每個DLL use AAA 然後再把DLL中 Tmytype宣告全部拿掉
如果Table有新增欄位 只要改AAA.pas中的Tmytype就好?

unit Unit1;

interface

uses AAA;

function getMytype:Tmytype;

implementation


function getMytype:Tmytype;
var tmptype:Tmytype;
begin

//取得取得唯一一筆Table1
result:=tmptype;
end;




這就像你每個Form都有放個 Button
也不用每個Unit 都需要宣告

TButton = class(TCustomButton)

只要use StdCtrls.pas就好

因為TButton 就已經放在StdCtrls.pas裡了



這都是最簡單的方法 為何不這樣做?


不然用{$I filename} {$INCLUDE filename}
編譯指令 把Tmytype 獨立一個文字擋 日後只要改該文字擋就好?
http://docs.embarcadero.com/products/rad_studio/delphiAndcpp2009/HelpUpdate2/EN/html/devcommon/compdirsincludefile_xml.html


另外你講的方法在DLL沒辦法這樣做 因為沒辦法共用變數
用PD說的方法一 sharememory也無法實現 因為Delphi是強型語言
編譯器在編譯時 就要找Tmytype 的宣告了
除非你能改用BPL RTTI
http://stackoverflow.com/questions/23823731/access-all-elements-of-a-record-using-rtti


不了解的問題點就是 簡單的方法不用 為啥要在兜圈子?
mnsf
初階會員


發表:104
回覆:90
積分:48
註冊:2003-11-25

發送簡訊給我
#10 引用回覆 回覆 發表時間:2015-10-27 17:50:20 IP:220.128.xxx.xxx 訂閱
我大約知道要怎麼做了,有空會試看看的,感謝
系統時間:2017-11-24 21:05:36
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!