在c或c++定義介面(函式)時,有時會使用預設值,這本來是無可厚非的。因為使用預設值,可以簡化呼叫。但在跨語言呼叫時,這往往會成為乙個新的問題。在c#和qt中呼叫這樣的dll時就會有這樣的問題。
我將qt呼叫c的dll的sum介面的第二個引數增加了乙個預設值,新的介面如下。
export int sum(int a,int b=100);
如果是按常規呼叫這個函式,我們寫成sum(1)和sum(1,200)都是可以的,但是在作為介面匯出為其他語言呼叫時,就得小心了。可能有人會這樣呼叫。
int main(int argc, char *argv)
sumfunction sum=(sumfunction)library.resolve("sum");
if (sum)
sumfunction sum=(sumfunction)library.resolve("sum");
if (sum)
{qdebug()<
執行結果如下
sum(1,888),結果是889,正是我們所期的值。
我在專案開發時,就在這裡著了道,開始時按正常的**呼叫(以前的**使用的是省去預設引數的介面)進行移值了,結果執行結果怎麼做都不對,後來檢視了介面文件,發現還有乙個預設值,然後加進去,再次執行,一切正常了。
折騰了很久,總是找到了問題。在c#呼叫dll時,也有碰到類似的問題。
總結了一下:
1.在呼叫dll介面時,一定要採用全參呼叫(顯式),不管有沒有預設值。
2.移值以前的**時,要注意語言的特性,尤其是在引數的數量和型別上。
棧 呼叫約定 函式預設值 inline函式
data存放已初始化但初始化不為0的資料 bss存放未初始化或初始化為0的資料 強弱符號 強符號 已初始化的全域性變數 弱符號 未初始化的全域性變數 規則 1 兩強符號 重定義錯誤 2 一強一弱,選強符號 3 兩弱符號,針對編譯器不同選擇不同 函式堆疊呼叫 move 移值 lea 移位址 四個暫存器...
C 筆記 函式堆疊呼叫 呼叫約定 形參預設值
1.通過加斷點 除錯 視窗 轉到反彙編可以檢視函式的堆疊呼叫過程 includeint sum int lhs,int rhs int main 知識點補充 1.底層對於變數沒有使用變數名進行區分而是使用棧底指標偏移量進行區分。2.等號是右結合性,先運算等號的右邊。3.對小於8位元組的返回值是交給e...
SQL建立和呼叫有預設值的儲存過程
先建立乙個有預設值的儲存過程 create procedure usp unpass subname varchar 50 score int 60 有預設值的引數放到最後 asselect score go 該儲存過程有2個引數 其中 score預設值為60 呼叫這個儲存過程的放法及說明如下 呼叫...