我想調用從OpenSSL庫此功能下面prototy定義:語義衝突傳遞指針爲const指針字節數組
X509 *d2i_X509(X509 **px, const unsigned char **in, int len);
第二個參數in
定義爲const unsigned char **
因爲:
- d2i_X509將不會修改由
*in
指向的緩衝區中的數據 *in
將增加從數據分析的數據量 緩衝。
現在這個原型是一個問題,因爲據我所知,該函數不能被稱爲以下方式,據我所知,API是調用它的正常方式(錯誤管理代碼已刪除讓事情變得更簡單):
unsigned char buffer[2048];
unsigned char * end = buffer;
unsigned char * p = buffer;
end += read(fd, p, 2048);
certlen1 = parseint(&p);
X509 * cert1 = d2i_x509(NULL, &p, certlen1);
certlen2 = parseint(&p);
X509 * cert2 = d2i_x509(NULL, &p, certlen2);
如果我嘗試編譯上面的代碼,它說:
error: invalid conversion from 'unsigned char**' to 'const unsigned char**'
我理解消息的理由(解釋here例如),但在這種特殊情況下日基本原理不適用於它的文檔中的函數狀態,它只會增加值*in
,不要爲它指派一個不相關的指針。
我不能改變p的類型爲const unsigned char *
,因爲上面的代碼實際上是簡化的,指針隱藏在一些執行讀和寫的抽象IO對象後面。與以前的IO對象的好處是保持對稱的讀寫代碼在一起,可以使用兩個單獨的指針來讀寫我的IO對象,但總體上這樣做的好處是非常小(如果不是負數)並添加很多合成噪音。由於某些外部不相關的API調用而強迫IO對象發生這種深度內部變化,看起來真的很舒服。
解決方案可能是執行轉換,甚至根本不使用返回的指針值(因爲我有尺寸參數),但它也不會感覺正確。似乎d2i_X509的原型沒有包含足夠的信息,或者編譯器的const檢查規則在這種情況下過於嚴格。
如何從C++調用這樣的API?現在我只會使用演員陣容,因爲我覺得這是一個較小的邪惡,但有沒有更好的辦法?
你在技術上是正確的,但完全除點,雖然過於simplyfing我的實際代碼,我有點過頭了。實際上,我有第二個指針'end',它是通過讀取遞增的,certlen1和certlen2是用p從緩衝區開始解析和提取的,並且沿着方向遞增。另外,p存儲在一些不透明的對象中,這些對象在緩衝區上執行讀取和寫入操作,並(檢查邊界)。雖然可能使內部p常量是一個真正的負擔,沒有明確的好處。換句話說,如果它是玩具而不是真正的程序,那麼建議的提議將是可能的。 – kriss
我並不確定它比演員表更好(看起來像是對常規檢查系統犯規的方式),但是這絕對是避免投射的一種可能的解決方案。 – kriss