[英]Create a CByteArray from a CPointer in Visual Works Smalltalk
[英]Create a const char ** in Visual Works image
我應該如何創建一個(const char **)將其傳遞給 C function?
假設我的 const char ** 被命名為prompts
然后:
user := 'User:' copyToHeap: #malloc:.
pwd := 'Password:' copyToHeap: #malloc:.
prompts := (ByteArray new: 64) copyToHeap: #malloc:.
prompts copyAt: 0 from: (user referentAddress asByteArraySize: 32) size: 4 startingAt: 1.
prompts copyAt: 31 from: (pwd referentAddress asByteArraySize: 32) size: 4 startingAt: 1.
所以prompts
是一個 64 位的數組,其中前 32 位是指向user
的指針,而后 32 位是指向pwd
的指針。
但是 C function 不工作。 在 GemStone 中可以正常工作:
prompts := CByteArray gcMalloc: 16.
user := CByteArray withAll: 'User:'.
pwd := CByteArray withAll: 'Password:'.
prompts uint64At: 0 put: user memoryAddress.
prompts uint64At: 8 put: pwd memoryAddress.
DLLCC 提供了一些非常接近 C 的 API。 您需要一個包含兩個 char 指針的數組。
prompts := CIntegerType char pointerType gcMalloc: 2.
然后你可以像這樣填充這個數組:
prompts at: 0 put: user.
prompts at: 1 put: pwd.
請注意,索引模仿 C 就像prompts[0]=user; prompts[1]=pwd;
prompts[0]=user; prompts[1]=pwd;
.
最后一件事,所有你malloc
,你必須然后free
,否則你會得到 memory 泄漏。
這意味着您應該更好地保護所有這些代碼
["your protected code here"]
ensure: [prompts free. user free. pwd free]`
……或者更糟……
["your protected code here"]
ensure:
[prompts isNil ifFalse: [prompts free].
"etc..."]`.
在早期開發中,我建議您最好使用gcMalloc
和gcMalloc:
。
經過思考
gcMalloc
對於user
和pwd
來說可能不是一個好主意。
這是因為prompts
將獲得包含在user
和pwd
對象中的 memory 地址的副本:它將指向相同的 memory 區域,但不會指向 Smalltalk 對象...
gcMalloc 只監控 Smalltalk 對象的垃圾收集。 因此,如果不再使用 Smalltalk 對象,C 堆可能會過早釋放,盡管其他一些對象指向相同的 C 堆...
例子:
fillPrompts
| user pwd prompts |
user := 'User:' copyToHeap: #gcMalloc:.
pwd := 'Password:' copyToHeap: #gcMalloc:.
prompts := CIntegerType char pointerType gcMalloc: 2.
prompts at: 0 put: user.
prompts at: 1 put: pwd.
^prompts
copyToHeap:
創建一個 CPointer object。 只要該方法處於活動狀態,它的上下文就指向那些對象(通過堆棧上的插槽)。
但是這個方法返回后,沒有任何 object 指向 CPointer 對象。
如果發生一些垃圾回收,它們指向 C 堆的關聯指針將被釋放。
但prompts
仍然包含對已釋放的 memory(所謂的懸空指針)的引用。
DLLCC 與 C 非常接近,因此在編寫 C 代碼時必須采取同樣的謹慎措施……而雙指針是絕大多數 Z0D61F8370CAD1D412F70B84D143E1 程序員的錯誤來源。
您不應該直接處理字節。 這在 C 中甚至沒有意義。
#gcCalloc
或#gcCopyToHeap
以便在仍然自動釋放的堆上分配 memory。 通常使用這些方法是安全的,因為您只需要在單個方法中將 memory 傳輸到 C。 假設是 c 函數復制這個 memory 本身以防以后需要它。#memberAt:put:
將成員分配給結構。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.