我在Python 3中使用(作爲c
導入)來執行C++共享庫。該庫使用裝入蟒蛇:使用ctypes在Python中解碼C const char *
smpLib = c.cdll.LoadLibrary(os.getcwd()+os.sep+'libsmpDyn.so')
功能之一有extern 'C'
聲明const char* runSmpModel(...)
。 Python函數原型進行編碼和運行:精美
proto_SMP = c.CFUNCTYPE(c.c_char_p,...)
runSmpModel = proto_SMP(('runSmpModel',smpLib))
res = runSmpModel(...)
這一切工作,但我無法將res
變量進行解碼,並獲得由C runSmpModel
函數傳遞出字符串。顯示res
的值(我使用ipython3
)爲b'\xd0'
。我在網上找到最好的解決辦法 - res.decode('utf-8')
給我的錯誤:
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xd0 in position 0: unexpected end of data
從runSmpModel
功能const char*
返回值來自
std::string scenID = SMPLib::SMPModel::runModel(...);
return scenID.c_str();
內runModel,如下所示它最終定義,其中scenName
是輸入字符串:
auto utcBuffId = newChars(500);
sprintf(utcBuffId, "%s_%u", scenName.c_str(), microSeconds); // catenate scenario name & time
uint64_t scenIdhash = (std::hash < std::string>() (utcBuffId)); // hash it
auto hshCode = newChars(100);
sprintf(hshCode, "%032llX", scenIdhash);
scenId = hshCode;
此特定的值3210應該是0000000000000000BBB00C6CA8B8872E
。我怎樣才能解碼這個字符串?
經過大量的進一步測試,我發現問題是從C函數傳遞的字符串的長度。如果字符串的長度不超過15個字符,則不會出現問題,但如果字符串的長度等於或大於16個字符,則不會有問題。對於最小工作實施例中,C-代碼是:
extern "C" {
const char* testMeSO()
{
string scenarioID = "abcdefghijklmnop";
return scenarioID.c_str();
}
}
和Python代碼是(相同smpLib的定義如上所示):
proto_TST = c.CFUNCTYPE(c.c_char_p)
testMeSO = proto_TST(('testMeSO',smpLib))
res = testMeSO()
print("Scenario ID: %s"%res.decode('utf-8'))
這使解碼錯誤,除非任何字符從C函數中的scenarioID
變量中刪除。所以看起來問題是「Python如何讀取長度超過15個字符的C char*
,使用。
一個字節不能突然變爲16.您遇到了不同的問題。 –
該調用返回了一個指向以'b'\ xd0 \ x00''開頭的緩衝區的指針。如果你確實需要幫助,你將不得不爲這個功能提供文檔 - 它做了什麼,參數是什麼,它在失敗時的表現如何,等等。 – eryksun
所有這些信息都是必需的 - 僅僅是關於這個返回值的信息是不合理的。我編輯了這個問題,添加了這些信息。 –