簡體   English   中英

在 Visual Works 圖像中創建一個 const char **

[英]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..."]`.

在早期開發中,我建議您最好使用gcMallocgcMalloc:

經過思考

gcMalloc對於userpwd來說可能不是一個好主意。

這是因為prompts將獲得包含在userpwd對象中的 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 中甚至沒有意義。

  1. 使用兩個 char* 成員創建一個結構,這更易於聲明、創建和處理。
  2. 使用#gcCalloc#gcCopyToHeap以便在仍然自動釋放的堆上分配 memory。 通常使用這些方法是安全的,因為您只需要在單個方法中將 memory 傳輸到 C。 假設是 c 函數復制這個 memory 本身以防以后需要它。
  3. 您可以使用#memberAt:put:將成員分配給結構。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM