[英]Create a const char ** in Visual Works image
How i should create a (const char **) to pass it to a C function?我应该如何创建一个(const char **)将其传递给 C function?
Let say my const char ** is named prompts
then:假设我的 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.
So prompts
is an array of 64bits where the first 32bits are a pointer to user
and the secods 32bits are a pointer to pwd
.所以prompts
是一个 64 位的数组,其中前 32 位是指向user
的指针,而后 32 位是指向pwd
的指针。
But the C function is not working.但是 C function 不工作。 In GemStone is working ok with:在 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 offers some API very close to C. DLLCC 提供了一些非常接近 C 的 API。 You need an array of two char pointers.您需要一个包含两个 char 指针的数组。
prompts := CIntegerType char pointerType gcMalloc: 2.
Then you can populate this array like this:然后你可以像这样填充这个数组:
prompts at: 0 put: user.
prompts at: 1 put: pwd.
Note that the indices mimic C like prompts[0]=user; prompts[1]=pwd;
请注意,索引模仿 C 就像prompts[0]=user; prompts[1]=pwd;
prompts[0]=user; prompts[1]=pwd;
. .
Last thing, everything you malloc
, you must then free
, otherwise you'll get memory leaks.最后一件事,所有你malloc
,你必须然后free
,否则你会得到 memory 泄漏。
That means that you shall better protect all this code with some这意味着您应该更好地保护所有这些代码
["your protected code here"]
ensure: [prompts free. user free. pwd free]`
...or worse... ……或者更糟……
["your protected code here"]
ensure:
[prompts isNil ifFalse: [prompts free].
"etc..."]`.
In early development, I suggest that you shall better use gcMalloc
and gcMalloc:
.在早期开发中,我建议您最好使用gcMalloc
和gcMalloc:
。
AFTER THOUGHTS经过思考
gcMalloc
is maybe not a such good idea for user
and pwd
. gcMalloc
对于user
和pwd
来说可能不是一个好主意。
This is because prompts
will get a copy of the address of memory contained in user
and pwd
objects: it will point to same memory zone, but will not point to the Smalltalk objects...这是因为prompts
将获得包含在user
和pwd
对象中的 memory 地址的副本:它将指向相同的 memory 区域,但不会指向 Smalltalk 对象...
gcMalloc only monitor the garbage collection of Smalltalk objects. gcMalloc 只监控 Smalltalk 对象的垃圾收集。 Hence, if Smalltalk objects are not more used, C heap might get freed prematurely despite some other objects point to the same C heap...因此,如果不再使用 Smalltalk 对象,C 堆可能会过早释放,尽管其他一些对象指向相同的 C 堆...
Example:例子:
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:
creates a CPointer object. copyToHeap:
创建一个 CPointer object。 As long as the method is active, its context point to those objects (thru slots on the stack).只要该方法处于活动状态,它的上下文就指向那些对象(通过堆栈上的插槽)。
But after return of this method, there is not any object pointing to the CPointer objects.但是这个方法返回后,没有任何 object 指向 CPointer 对象。
If some garbage collection occur, their associated pointer to C heap will be freed.如果发生一些垃圾回收,它们指向 C 堆的关联指针将被释放。
But prompts
still contain reference to already freed memory (the so called dangling pointers).但prompts
仍然包含对已释放的 memory(所谓的悬空指针)的引用。
DLLCC being very close to C, one must adopt the same care as when writing C code... And double pointers is a source of bugs for the vast majority of C programmers. DLLCC 与 C 非常接近,因此在编写 C 代码时必须采取同样的谨慎措施……而双指针是绝大多数 Z0D61F8370CAD1D412F70B84D143E1 程序员的错误来源。
You shouldn't work directly on the bytes.您不应该直接处理字节。 That doesn't even make sense in C.这在 C 中甚至没有意义。
#gcCalloc
or #gcCopyToHeap
in order to allocate memory on the heap that's still automatically freed.使用#gcCalloc
或#gcCopyToHeap
以便在仍然自动释放的堆上分配 memory。 Typically it's safe to use these methods because you only need that memory inside a single method to transfer it to C.通常使用这些方法是安全的,因为您只需要在单个方法中将 memory 传输到 C。 The assumption is that the c-function copies this memory itself in case it needs it later.假设是 c 函数复制这个 memory 本身以防以后需要它。#memberAt:put:
to assign members to the struct.您可以使用#memberAt:put:
将成员分配给结构。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.