討論區快速選單
知識庫快速選單
程式設計俱樂部Facebook粉絲團 用最高效的方式管理MySQL 全方位AWS解決方案完整培訓
[ 回上頁 ] [ 討論區發言規則 ]
[分享]插件成了 header only 的罩門
更改我的閱讀文章字型大小
作者 : cxxlman(CxxlMan) C++優秀好手貼文超過1000則
[ 貼文 1033 | 人氣 3227 | 評價 1260 | 評價/貼文 1.22 | 送出評價 27 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2018/10/26 上午 11:45:56
插件成了 header only 的罩門

什麼是 header only? 可以先看此文了解一下 http://zevoid.blogspot.com/2012/04/c11-extern-template.html

簡單的說,header only 是把一個 class 的程式碼就包含在這個 class 中,而這個 class 就放在引入檔(.h)中供大家使用。有別於引入檔只放 class 介面,程式碼則放在 .cpp 中。

header only 的好處是執行快,因一大部份的函數可以用 inline 的方式呼叫,另外也不用再加 .cpp 或是還要連結程式庫(lib 或 dll)。

但有一個不得不面對的問題,class 的程式碼因不放在特定的 .cpp 中,那麼使用它的模組(exe、lib、dll)都得編譯出各別的執行碼,一般來說除了程式會比較胖之外,也沒有其它不好的影響。但是遇到插件就出問題了。

插件是一個 dll 檔,特點是要用的時候才載入,不用的時候可以卸載,但若某一個 class 產生的物件,其執行碼在那個被卸載的 dll 中,就會出大問題了,以下範例程式就是在演示這種情況。


/*
** test.h : header only 形式的引入檔
*/

class Test
{
 const char Str[20]{ "I am Test" };
public:
 Test()
 {
 }
 ~Test() {};

 // inline
 const char *GetStr1() const
 {
  return Str;
 }

 // 迫使使用端一定得使用服務端提供的實作碼
 virtual const char *GetStr2() const
 {
  return Str;
 }
};


/*
** dllmain.cpp : 定義 DLL 應用程式的進入點。
*/

#include "test.h"

extern "C" __declspec(dllexport)
Test *__cdecl GetTest()
{
 return new Test;
}

/*
** customer.cpp: 定義主控台應用程式的進入點。
*/

#include <Windows.h>
#include <test.h>
#include <iostream>

using namespace std;

HINSTANCE DLLInst;
Test*(__cdecl *GetTest)();

int main()
{

 DLLInst = LoadLibraryW(L"Server.dll");
 GetTest = (decltype(GetTest))GetProcAddress(DLLInst, "GetTest");

 Test *pTest = GetTest(); 
 const char *Str1;
 const char *Str2;

 Str1 = pTest->GetStr1();
 cout << "Str1: " << Str1 << endl;
 Str2 = pTest->GetStr2();
 cout << "Str2: " << Str2 << endl;

 FreeLibrary(DLLInst);

 Str1 = pTest->GetStr1();
 cout << "Str1: " << Str1 << endl;
 Str2 = pTest->GetStr2();
 cout << "Str2: " << Str2 << endl;

 return 0;
}


作者 : ice_emissary(燃燒的大地) 貼文超過200則
[ 貼文 375 | 人氣 0 | 評價 1740 | 評價/貼文 4.64 | 送出評價 16 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2018/10/26 下午 12:14:46
這有什麼好罩門不罩門的?

既然是外掛程式,當然是要去呼叫外掛提供的執行碼啊!不然還叫外掛?
那當外掛卸載之後,還去呼叫那個外掛的函式,那當然是墜毀啊!
會在卸載後還去呼叫別人家函式的話,這就是確實主程式的問題無誤。

事實上,外掛程式的標頭檔對於主程式而言是沒有用處的。
做為一個外掛程式,只有二進位碼會被主程式使用。
所以拿標頭檔來說事本身就是有問題的問題。

雖然你提的這個文題完全是主程式規劃不當造成,但其實這種外掛模式本身是有很多危險的缺點。
動態執行檔在載入以後就是主程式的一部份了,所以可以訪問、甚至覆寫主程式的記憶體內容,
不論是無意的、設計上允許的、還是故意覆寫不該覆寫的位置皆可被允許。
因此一個外掛的缺陷是可以讓整個主程式掛掉的,甚至若你對主程式了解足夠的話,還可以做出很多竄改。
所以動態程式庫形式的外掛模式非常倚賴寫外掛的人的素質。

也因此,很多現在的大型程式的外掛模式有漸漸的從 shared library 改為採用獨立行程再透過 RPC 通訊的 service 模式改變的現象,
可能是受夠了各種低品質外掛把自己名聲搞殘的事情吧!
作者 : cxxlman(CxxlMan) C++優秀好手貼文超過1000則
[ 貼文 1033 | 人氣 3227 | 評價 1260 | 評價/貼文 1.22 | 送出評價 27 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2018/10/26 下午 01:01:18

>這有什麼好罩門不罩門的?
>
>既然是外掛程式,當然是要去呼叫外掛提供的執行碼啊!不然還叫外掛?
>那當外掛卸載之後,還去呼叫那個外掛的函式,那當然是墜毀啊!
>會在卸載後還去呼叫別人家函式的話,這就是確實主程式的問題無誤。

這裡說的 header only 這一塊的問題(Ex: Boost C++ Library)
這裡的例子是 class Test

>
>事實上,外掛程式的標頭檔對於主程式而言是沒有用處的。
>做為一個外掛程式,只有二進位碼會被主程式使用。
>所以拿標頭檔來說事本身就是有問題的問題。

不是在講外掛,而是在講 class Test 被外掛用到了就糟了

>雖然你提的這個文題完全是主程式規劃不當造成,但其實這種外掛模式本身是有很多危險的缺點。
>動態執行檔在載入以後就是主程式的一部份了,所以可以訪問、甚至覆寫主程式的記憶體內容,
>不論是無意的、設計上允許的、還是故意覆寫不該覆寫的位置皆可被允許。
>因此一個外掛的缺陷是可以讓整個主程式掛掉的,甚至若你對主程式了解足夠的話,還可以做出很多竄改。
>所以動態程式庫形式的外掛模式非常倚賴寫外掛的人的素質。

>也因此,很多現在的大型程式的外掛模式有漸漸的從 shared library 改為採用獨立行程再透過 RPC 通訊的 service 模式改變的現象,
>可能是受夠了各種低品質外掛把自己名聲搞殘的事情吧!

RPC 的確是最佳解決方案,但任何功能就得用 RPC 也未免太小題大作了,能想像把 Boost C++ Library 做成 RPC 嗎,若能做到 C++ 就不是 C++ 了,或者說 C++ 是一大進步,好美好的景象,微軟 COM 就是 RPC,也曾有這雄心壯志吧


作者 : ice_emissary(燃燒的大地) 貼文超過200則
[ 貼文 375 | 人氣 0 | 評價 1740 | 評價/貼文 4.64 | 送出評價 16 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2018/10/26 下午 02:04:35
其實,外掛的坑也不是只有 header function。多了去了。
其實,C++ 的坑也不是只有 header function。多了去了。

Header function 乃至於 header module 的最大最凸出優點只有一個,就是使用的時候只要 include 就可以了!
當然缺點也很明顯,就是你已經知道的那些,會讓程式碼膨脹的很快。
其實整個 STL 模組基本就是 header module,因為使用模版設計的程式會卡到實例化的問題,最終也只能寫成 header module。
所以任何程式使用了 STL 就會膨脹,此乃正常現象。
另一個明顯問題就是編譯速度會很慢,請自行體會。

你貼的程式碼的問題是因為使用虛函式呼叫,可是虛函式本身只能執行時期繫結,這是標準定死的。
在這個情況下,什麼 inline 什麼的都是浮雲,如果程式員沒有概念的話就會踩坑。

但整個 C/C++ 的大坑小坑多了去了,所以這個問題其實微不足道。這就是為什麼實習生寫 C++ 程式往往會爆炸的根本原因。
沒辦法,C/C++ 的設計哲學就是這樣,它本身非常相信程式員,也非常依賴高素質的程式員。
程式員必須要很了解 C/C++、很了解系統、很了解電腦,才能夠寫出好程式。
作者 : cxxlman(CxxlMan) C++優秀好手貼文超過1000則
[ 貼文 1033 | 人氣 3227 | 評價 1260 | 評價/貼文 1.22 | 送出評價 27 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2018/10/26 下午 04:25:15


>你貼的程式碼的問題是因為使用虛函式呼叫,可是虛函式本身只能執行時期繫結,這是標準定死的。
>在這個情況下,什麼 inline 什麼的都是浮雲,如果程式員沒有概念的話就會踩坑。

當把 dll 卸載後,GetStr1() 還是可以執行的,因是 inline,執行碼在使用端,不是浮雲
作者 : ice_emissary(燃燒的大地) 貼文超過200則
[ 貼文 375 | 人氣 0 | 評價 1740 | 評價/貼文 4.64 | 送出評價 16 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2018/10/26 下午 05:12:13
>>你貼的程式碼的問題是因為使用虛函式呼叫,可是虛函式本身只能執行時期繫結,這是標準定死的。
>>在這個情況下,什麼 inline 什麼的都是浮雲,如果程式員沒有概念的話就會踩坑。
>
>當把 dll 卸載後,GetStr1() 還是可以執行的,因是 inline,執行碼在使用端,不是浮雲
>

你跟我扯這個!
GetStr1 是虛函式嗎?我那一段的說明明明是針對虛函式來的。

我們就把應用定在外掛用途好了。
這樣,class Test 肯定就是外掛的類別了是吧?Test 的實體也肯定就是外掛模組產生的實體了對吧?
那麼不管是不是外掛,當一個物件實體被銷毀後還去呼叫它的成員,這不就是找死行為嗎?

對於已銷毀的物件實體,呼叫部份函式會導致問題的這個想法是不對的!反而應該要這樣解釋:
已銷毀的物件實體,大部份的呼叫都是不安全的,只有部份的函式僥倖可以呼叫而沒有異常;
但即使是這樣,呼叫已銷毀實體成員的行為仍極不鼓勵使用。

所以,不管實際上呼叫 GetStr1 是不是正常?在 Test 的實體銷毀後這件事情就不應該發生,否則即是不良寫法;
而若是 Test 還未解構就直接把外掛卸載,這就是主程式的外掛管理確定有問題,這件事也不應該發生。

最終的意思就是,模組卸載後還去呼叫 GetStr1 就是不應該發生的寫法,而呼叫以後竟然還可以用這點也只是僥倖而已!
作者 : cxxlman(CxxlMan) C++優秀好手貼文超過1000則
[ 貼文 1033 | 人氣 3227 | 評價 1260 | 評價/貼文 1.22 | 送出評價 27 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2018/10/26 下午 08:42:08

>>>你貼的程式碼的問題是因為使用虛函式呼叫,可是虛函式本身只能執行時期繫結,這是標準定死的。
>>>在這個情況下,什麼 inline 什麼的都是浮雲,如果程式員沒有概念的話就會踩坑。
>>
>>當把 dll 卸載後,GetStr1() 還是可以執行的,因是 inline,執行碼在使用端,不是浮雲
>>
>
>你跟我扯這個!
>GetStr1 是虛函式嗎?我那一段的說明明明是針對虛函式來的。
>
>我們就把應用定在外掛用途好了。
>這樣,class Test 肯定就是外掛的類別了是吧?Test 的實體也肯定就是外掛模組產生的實體了對吧?
>那麼不管是不是外掛,當一個物件實體被銷毀後還去呼叫它的成員,這不就是找死行為嗎?
>
>對於已銷毀的物件實體,呼叫部份函式會導致問題的這個想法是不對的!反而應該要這樣解釋:
>已銷毀的物件實體,大部份的呼叫都是不安全的,只有部份的函式僥倖可以呼叫而沒有異常;
>但即使是這樣,呼叫已銷毀實體成員的行為仍極不鼓勵使用。
>
>所以,不管實際上呼叫 GetStr1 是不是正常?在 Test 的實體銷毀後這件事情就不應該發生,否則即是不良寫法;
>而若是 Test 還未解構就直接把外掛卸載,這就是主程式的外掛管理確定有問題,這件事也不應該發生。
>
>最終的意思就是,模組卸載後還去呼叫 GetStr1 就是不應該發生的寫法,而呼叫以後竟然還可以用這點也只是僥倖而已!

外掛卸載後,Test 產生的實體仍然存在,因它是建立在 heap 不是在外掛,在這例子,GetStr1() 的執行碼一定會在使用遄,這是 inline 一定要的

作者 : cxxlman(CxxlMan) C++優秀好手貼文超過1000則
[ 貼文 1033 | 人氣 3227 | 評價 1260 | 評價/貼文 1.22 | 送出評價 27 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2018/10/27 下午 06:19:35
會造成這樣的結果,是因為 header only 讓一個物件的成份散佈在各處,這造成各模組必須處於緊密結合的狀態,喪失了鬆散結構的機會,自然沒法使用外掛機制
作者 : cxxlman(CxxlMan) C++優秀好手貼文超過1000則
[ 貼文 1033 | 人氣 3227 | 評價 1260 | 評價/貼文 1.22 | 送出評價 27 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2018/10/28 上午 11:35:07
解決的辦法就是乖乖把在 header only 的執行程式碼移入 cpp,徹底放棄 header only,對於 template class 和第三方的 header only,就繼承出實作類別,再把實作程式碼放入 cpp,這樣就能解決執行碼到處散播的問題,經實驗是可以成功做出外掛。

至於外掛的卸載問題,也就是如何知道已不使用可以安全卸載了,那是另一層面的技術問題。至少經以上處理後,外掛機制變得可行了
作者 : cxxlman(CxxlMan) C++優秀好手貼文超過1000則
[ 貼文 1033 | 人氣 3227 | 評價 1260 | 評價/貼文 1.22 | 送出評價 27 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2018/10/28 下午 01:48:15
現在談談要怎麼安全地卸載外掛,概念是利用智能指標達到外掛不再有被使用時就自動缷載

1. 定義一個 class FreeDll,這個負責在解構時卸載外掛
2. 定義一個 class Plugin,規定任何由外掛產生的物件都必須繼承自這個 class,而這 class 其中有一個屬性
class Plugin
{
 std::shared_ptr<FreeDll> FreeDll_Ptr;
};
3. 然後規定要得到外掛產生的物件必須經過一個機制,這機制其中一項任務就是把 FreeDll 放入 FreeDll_Ptr

概念上就是這樣,當然實務上要加入自己的考量,或是用更好的辦法,祝大家開掛成功無往不利^^
作者 : ice_emissary(燃燒的大地) 貼文超過200則
[ 貼文 375 | 人氣 0 | 評價 1740 | 評價/貼文 4.64 | 送出評價 16 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2018/10/28 下午 08:39:42
雖然看似如此,但實際上這個問題不會發生也不應該發生。

主程式不可能會去呼叫 class Test 的 inline 函式,因為:

1. 若 Test 是外掛的實做版本的話,主程式不可能去引用這個標頭進而呼叫這個 inline 函式。
否則每當新增一個外掛的時候,主程式就要加入外掛標頭然後重新編譯一次?

2. 若 Test 是主程式端的所使用的外掛標頭,則這裡不應該出現 inline 函式,甚至不應該實做任何函式。
主程式之所以需要外掛就是因為需要有不同外掛的不同實做函式,若主程式的外掛標頭把函式功能都做好了,那還需要外掛嗎?
當然這裡排除主程式端的外掛封裝模組,這比較複雜一點。

3. 外掛程式需要提供主程式所開列的函式之實做,就算寫成 inline,也會被編譯器編成非 inline 版本來用,所以沒差。
事實上,外掛程式通常不會直接製做 Test 類別,而是會繼承這個類別後創建一個新的類別。
所以 Test 類別上的函式「實做」為外掛而言是沒有存在意義的,因為外掛要的是需要製做的功能「介面」,
所以這個 Test 類別通常會是個純虛類別。
作者 : cxxlman(CxxlMan) C++優秀好手貼文超過1000則
[ 貼文 1033 | 人氣 3227 | 評價 1260 | 評價/貼文 1.22 | 送出評價 27 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2018/10/29 上午 11:11:51
Test 只是一個 class,而且是一個 header only 形式的 class,任何模組都可以產生和使用它的實例,在這個例子精確的說只是經由外掛取得一個 Test 實例罷了

inline 可以把它看作一個巨集,呼叫等於是把巨集展開,所以執行程式碼一定在使用端

由表面看 class 會把一堆資料和函數包在一起,那只是一個假象,由技術面來看,和 C 的函數在處理一個 struct 沒什麼不同

你提到 "每當新增一個外掛的時候,主程式就要加入外掛標頭然後重新編譯一次?",這就很有討論的空間了,這就要看採用怎樣的設計模式,彈性有多大,不過我可以直接告訴你,外掛的確可以做到不用重新編譯。通常一個外掛(其實所有的程式庫都一樣),要使用它的單元就知道怎麼使用它,主程式只要做好調配的工作就行了。

這麼說有點玄,我舉一個簡單的例子,一個程式須要在作業系統中執行,若有人寫了一個新程式,作業系統是不是須再編譯一次,不用吧,作業系統只要把某個 單元 正確的拿給會使用它的 單元 就行了
作者 : ice_emissary(燃燒的大地) 貼文超過200則
[ 貼文 375 | 人氣 0 | 評價 1740 | 評價/貼文 4.64 | 送出評價 16 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2018/10/29 上午 11:39:49
太好了!那你先告訴我,要怎麼樣在主程式不重新編譯的情況下增加一個新的外掛,而且是 header only 的外掛?
我是真的沒想出好方法所以虛心求教,畢竟這做得到的話,有些事情會很方便。
而也只有在上述這事情做得到的情況下,有關外掛 inline function 的討論才有實質意義對吧?
作者 : cxxlman(CxxlMan) C++優秀好手貼文超過1000則
[ 貼文 1033 | 人氣 3227 | 評價 1260 | 評價/貼文 1.22 | 送出評價 27 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2018/10/29 上午 11:50:06

>太好了!那你先告訴我,要怎麼樣在主程式不重新編譯的情況下增加一個新的外掛,而且是 header only 的外掛?
>我是真的沒想出好方法所以虛心求教,畢竟這做得到的話,有些事情會很方便。
>而也只有在上述這事情做得到的情況下,有關外掛 inline function 的討論才有實質意義對吧?
 
這不是三言兩語可以說清楚,牽扯到許多技術,不過有人做成程式庫可以直接用,這裡推薦一個 ^^

http://blog.cxxl3d.tk/2015/10/cxxlman2-class-lib.html
作者 : ice_emissary(燃燒的大地) 貼文超過200則
[ 貼文 375 | 人氣 0 | 評價 1740 | 評價/貼文 4.64 | 送出評價 16 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2018/10/29 下午 04:11:38
>這不是三言兩語可以說清楚,牽扯到許多技術,不過有人做成程式庫可以直接用,這裡推薦一個 ^^
>
>http://blog.cxxl3d.tk/2015/10/cxxlman2-class-lib.html

一整坨右一整坨的程式碼!
你就不能重點說明關鍵的原理?或至少指點一下程式中的哪個段落是處理你講的什麼部份嗎?
作者 : cxxlman(CxxlMan) C++優秀好手貼文超過1000則
[ 貼文 1033 | 人氣 3227 | 評價 1260 | 評價/貼文 1.22 | 送出評價 27 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2018/10/29 下午 04:45:53
好的,我另外開一個主題來說說,你稍待
作者 : ma_hty(白老鼠(Gary))討論區板主 OpenGL卓越專家DirectX優秀好手C++頂尖高手貼文超過2000則人氣指數超過70000點
[ 貼文 2163 | 人氣 89850 | 評價 10090 | 評價/貼文 4.66 | 送出評價 79 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2018/10/31 上午 12:57:31

>太好了!那你先告訴我,要怎麼樣在主程式不重新編譯的情況下增加一個新的外掛,而且是 header only 的外掛?
>我是真的沒想出好方法所以虛心求教,畢竟這做得到的話,有些事情會很方便。
>而也只有在上述這事情做得到的情況下,有關外掛 inline function 的討論才有實質意義對吧?


燃燒的大地兄, 加油呀. 給你打氣一下. 樓主 這麼熱血地去論述畫蛇添足的破爛, 本來大大力吐糟一下的. 不過, 有你苦口婆心的指正了樓主, 我除了給你一個讚, 也沒必要補充了. 讚!
作者 : ice_emissary(燃燒的大地) 貼文超過200則
[ 貼文 375 | 人氣 0 | 評價 1740 | 評價/貼文 4.64 | 送出評價 16 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2018/10/31 下午 12:14:45
感謝老鼠兄的誇獎,實在不敢當!

其實我後來想一想,這是可以做到的,而且發現已經有軟體這樣做了。
只要主程式做一個語法解析器去分析外掛的標頭,就可以分析出外掛想要做什麼,然後由主程式代為完成。
這樣,外掛的二進位碼反而不重要了,所有外掛都只要標頭檔就好;
事實上這就是把程式庫形式的外掛變換為腳本形式的外掛。

不過若能做到這個份上,一般也不會選用 C/C++ 做為外掛使用的語言;一般會:
1. 自己制定外掛語言,這樣語法可以比較簡單,解析器也比較容易製做。
2. 使用其他的腳本語言做為外掛語言,這樣可以使用現成存在的腳本語言解譯器,例如 Python,
我最近在看的 Nautilus Python extension 就是。
作者 : ma_hty(白老鼠(Gary))討論區板主 OpenGL卓越專家DirectX優秀好手C++頂尖高手貼文超過2000則人氣指數超過70000點
[ 貼文 2163 | 人氣 89850 | 評價 10090 | 評價/貼文 4.66 | 送出評價 79 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2018/11/1 下午 03:47:40

>感謝老鼠兄的誇獎,實在不敢當!
>
>其實我後來想一想,這是可以做到的,而且發現已經有軟體這樣做了。
>只要主程式做一個語法解析器去分析外掛的標頭,就可以分析出外掛想要做什麼,然後由主程式代為完成。
>這樣,外掛的二進位碼反而不重要了,所有外掛都只要標頭檔就好;
>事實上這就是把程式庫形式的外掛變換為腳本形式的外掛。
>
>不過若能做到這個份上,一般也不會選用 C/C++ 做為外掛使用的語言;一般會:
>1. 自己制定外掛語言,這樣語法可以比較簡單,解析器也比較容易製做。
>2. 使用其他的腳本語言做為外掛語言,這樣可以使用現成存在的腳本語言解譯器,例如 Python,
>我最近在看的 Nautilus Python extension 就是。

樓主在鼓吹的 是多此一舉的行動. 甚麼說呢...

為啥要架空C++編譯架構? 這是本沒倒置呀.

用C++, 就是想要它嚴緊的編譯架構, 另加對程式運作的全面控制. 架空了它, 那C++的優勢就全沒了. 就彷彿是... 跟快餐店櫃^小姐說: "我要買一杯奶茶, 奶和茶要請不要加." (^^"... 這笑話太冷了吧)

當然, 靈活的控制介面, 是有需求的. 可是, 我們已有很多... 很多... ... 很多... ... ... 的編程語言在幹這活了. 由電腦還沒普及的古代開始, 已有這一類介面 (如 shell script), 一路走來而累積下來的發展, 豈是樓主亂糟糟地妄想一下 就能把C++改裝成能與之相比?

那麼想要靈活的介面, 直接換一個靈活的介面即可, 例如你說的Python.

想要 嚴緊的編譯架構,+對程式運作的全面控制, 又同時想要 靈活的介面 的話, 也可以考慮用C++編出程式 然後在靈活的介面裡使用. 這也是行之有效的主流行動.

至於樓主的妄想呢... "若-能-理-解-就-不-妙-了"!.










 板主 : simula
 > C++ - 討論區
 - 最近熱門問答精華集
 - 全部歷史問答精華集
 - C++ - 知識庫
  ■ 全站最新Post列表
  ■ 我的文章收藏
  ■ 我最愛的作者
  ■ 全站文章收藏排行榜
  ■ 全站最愛作者排行榜
  ■  月熱門主題
  ■  季熱門主題
  ■  熱門主題Top 20
  ■  本區Post排行榜
  ■  本區評價排行榜
  ■  全站專家名人榜
  ■  全站Post排行榜
  ■  全站評價排行榜
  ■  全站人氣排行榜
 請輸入關鍵字 
  開始搜尋
 
Top 10
評價排行
C++
1 Raymond 13050 
2 青衫 4760 
3 simula 4690 
4 coco 4030 
5 白老鼠(Gary) 3670 
6 ozzy 2540 
7 Ben 2250 
8 Anderson 1960 
9 windblown 1650 
10 Kenny 1560 
C++
  專家等級 評價  
  一代宗師 10000  
  曠世奇才 5000  
  頂尖高手 3000  
  卓越專家 1500  
  優秀好手 750  
Microsoft Internet Explorer 6.0. Screen 1024x768 pixel. High Color (16 bit).
2000-2018 程式設計俱樂部 http://www.programmer-club.com.tw/
0.328125