How to get UnsafePointer or UnsafeMutablePointer from ContiguousArray?


(Sergey Kuratov) #1

Hello!

I got some problem with ContiguousArray<->C interaction - I can't
get address of array buffer to process in native code.

Could somebody help me to get?

Actually I also didn't find init(Array<...>) in UnsafePointer interface.

I wonder what initialiser is used when UnsafePointer<T>(Array<T>)?

Here is sample code:

class Test {

var a = 0

}

var testarr1 : Array<Test> = [ Test(), Test() ]

var testarr2 : ContiguousArray<Test> = [ Test(), Test() ]

let arrPtr1 = UnsafePointer<Test>(testarr1)

let arrPtr2 = UnsafePointer<Test>(testarr2) <- error "Cannot invoke
initialiser..."


(David Turnbull) #2

You want testarr2.withUnsafeMutableBufferPointer().

-david

···

On Wed, Feb 10, 2016 at 11:09 PM, Sergey Kuratov via swift-users < swift-users@swift.org> wrote:

Hello!

I got some problem with ContiguousArray<->C interaction - I can't
get address of array buffer to process in native code.

Could somebody help me to get?

Actually I also didn't find init(Array<...>) in UnsafePointer interface.

I wonder what initialiser is used when UnsafePointer<T>(Array<T>)?

Here is sample code:

class Test {

var a = 0

}

var testarr1 : Array<Test> = [ Test(), Test() ]

var testarr2 : ContiguousArray<Test> = [ Test(), Test() ]

let arrPtr1 = UnsafePointer<Test>(testarr1)

let arrPtr2 = UnsafePointer<Test>(testarr2) <- error "Cannot invoke
initialiser..."

_______________________________________________
swift-users mailing list
swift-users@swift.org
https://lists.swift.org/mailman/listinfo/swift-users


(Dmitri Gribenko) #3

Just pass the array to your C function that accepts an unsafe pointer.
The compiler will perform the conversion automatically.

You can also use the withUnsafeMutableBufferPointer method, but make
sure to use the pointer only inside of the closure. Don't try to get
a pointer to array contents and persist it. The pointer will become
invalid.

Dmitri

···

On Wed, Feb 10, 2016 at 11:09 PM, Sergey Kuratov via swift-users <swift-users@swift.org> wrote:

Hello!

I got some problem with ContiguousArray<->C interaction - I can't get
address of array buffer to process in native code.

--
main(i,j){for(i=2;;i++){for(j=2;j<i;j++){if(!(i%j)){j=0;break;}}if
(j){printf("%d\n",i);}}} /*Dmitri Gribenko <gribozavr@gmail.com>*/


(Dmitri Gribenko) #4

Re-adding swift-users back.

Thank you, Dmitri!

I wonder how this automatic transformation to unsafe pointer happens (I
guess elements buffer has some offset from array object memory) ?

The compiler knows how to extract the pointer from the array, and how
to extend its lifetime to ensure it is not deallocated before the C
function returns.

Can I define similar for my Swift classes ?

No. What would be your usecase?

Dmitri

···

On Wed, Feb 10, 2016 at 11:49 PM, Sergey Kuratov <ksubox.swift@gmail.com> wrote:

--
main(i,j){for(i=2;;i++){for(j=2;j<i;j++){if(!(i%j)){j=0;break;}}if
(j){printf("%d\n",i);}}} /*Dmitri Gribenko <gribozavr@gmail.com>*/


(Sergey Kuratov) #5

Can I define similar for my Swift classes ?

No. What would be your use case?

I also could have my Swift object with several members, but when send to
native part would like to send address exactly one of members.
Something like this:

// Swift part

class ABlock {

var channels = 2

var samplerate = 44100

var buffer : UnsafeMutablePointer<Int16>

init() {

buffer = UnsafeMutablePointer<Int16>.alloc(2048)

}

deinit {

buffer.dealloc(2048)

}

}

var block = ABlock
generate(block) <- here I would like to send address of ABlock.buffer to
native part

// C part
void generate(int16_t *buf) {
...
}

···

On Thu, Feb 11, 2016 at 4:54 PM, Dmitri Gribenko <gribozavr@gmail.com> wrote:

Re-adding swift-users back.

On Wed, Feb 10, 2016 at 11:49 PM, Sergey Kuratov <ksubox.swift@gmail.com> > wrote:
> Thank you, Dmitri!
>
> I wonder how this automatic transformation to unsafe pointer happens (I
> guess elements buffer has some offset from array object memory) ?

The compiler knows how to extract the pointer from the array, and how
to extend its lifetime to ensure it is not deallocated before the C
function returns.

> Can I define similar for my Swift classes ?

No. What would be your usecase?

Dmitri

--
main(i,j){for(i=2;;i++){for(j=2;j<i;j++){if(!(i%j)){j=0;break;}}if
(j){printf("%d\n",i);}}} /*Dmitri Gribenko <gribozavr@gmail.com>*/


(Dmitri Gribenko) #6

I'd recommend to write a Swift wrapper for your C code that accepts
the class instance, and calls the generate() function with appropriate
arguments.

Dmitri

···

On Thu, Feb 11, 2016 at 12:13 AM, Sergey Kuratov <ksubox.swift@gmail.com> wrote:

Can I define similar for my Swift classes ?

No. What would be your use case?

I also could have my Swift object with several members, but when send to
native part would like to send address exactly one of members.
Something like this:

// Swift part

class ABlock {

var channels = 2

var samplerate = 44100

var buffer : UnsafeMutablePointer<Int16>

init() {

buffer = UnsafeMutablePointer<Int16>.alloc(2048)

}

deinit {

buffer.dealloc(2048)

}

}

var block = ABlock
generate(block) <- here I would like to send address of ABlock.buffer to
native part

// C part
void generate(int16_t *buf) {
...
}

--
main(i,j){for(i=2;;i++){for(j=2;j<i;j++){if(!(i%j)){j=0;break;}}if
(j){printf("%d\n",i);}}} /*Dmitri Gribenko <gribozavr@gmail.com>*/


(Dmitri Gribenko) #7

Oh, and since your class stores an unsafe pointer (and not an array),
you'd need to call _fixLifetime() on it after the your C function
returns, to ensure that the class instance can't be deallocated before
then. Unless you have other requirements though, I'd recommend just
storing an array though. Then you wouldn't need to care about
_fixLifetime().

Dmitri

···

On Thu, Feb 11, 2016 at 12:19 AM, Dmitri Gribenko <gribozavr@gmail.com> wrote:

On Thu, Feb 11, 2016 at 12:13 AM, Sergey Kuratov <ksubox.swift@gmail.com> wrote:

Can I define similar for my Swift classes ?

No. What would be your use case?

I also could have my Swift object with several members, but when send to
native part would like to send address exactly one of members.
Something like this:

// Swift part

class ABlock {

var channels = 2

var samplerate = 44100

var buffer : UnsafeMutablePointer<Int16>

init() {

buffer = UnsafeMutablePointer<Int16>.alloc(2048)

}

deinit {

buffer.dealloc(2048)

}

}

var block = ABlock
generate(block) <- here I would like to send address of ABlock.buffer to
native part

// C part
void generate(int16_t *buf) {
...
}

I'd recommend to write a Swift wrapper for your C code that accepts
the class instance, and calls the generate() function with appropriate
arguments.

--
main(i,j){for(i=2;;i++){for(j=2;j<i;j++){if(!(i%j)){j=0;break;}}if
(j){printf("%d\n",i);}}} /*Dmitri Gribenko <gribozavr@gmail.com>*/


(Sergey Kuratov) #8

Got it.

Thank you.

···

On Thu, Feb 11, 2016 at 5:19 PM, Dmitri Gribenko <gribozavr@gmail.com> wrote:

On Thu, Feb 11, 2016 at 12:13 AM, Sergey Kuratov <ksubox.swift@gmail.com> > wrote:
>>> Can I define similar for my Swift classes ?
>
>>No. What would be your use case?
>
> I also could have my Swift object with several members, but when send to
> native part would like to send address exactly one of members.
> Something like this:
>
> // Swift part
>
> class ABlock {
>
> var channels = 2
>
> var samplerate = 44100
>
> var buffer : UnsafeMutablePointer<Int16>
>
> init() {
>
> buffer = UnsafeMutablePointer<Int16>.alloc(2048)
>
> }
>
> deinit {
>
> buffer.dealloc(2048)
>
> }
>
> }
>
>
> var block = ABlock
> generate(block) <- here I would like to send address of ABlock.buffer to
> native part
>
> // C part
> void generate(int16_t *buf) {
> ...
> }

I'd recommend to write a Swift wrapper for your C code that accepts
the class instance, and calls the generate() function with appropriate
arguments.

Dmitri

--
main(i,j){for(i=2;;i++){for(j=2;j<i;j++){if(!(i%j)){j=0;break;}}if
(j){printf("%d\n",i);}}} /*Dmitri Gribenko <gribozavr@gmail.com>*/


(Sergey Kuratov) #9

I try to find _fixLifetime in standard library and finally can't :frowning: But
function exists in reality and I can call it.
I also found some discussion about
https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20151228/005017.html

So as I can understand it's not fixed API to manage scoped life and
probably will be changed in the future.

···

On Thu, Feb 11, 2016 at 5:38 PM, Dmitri Gribenko <gribozavr@gmail.com> wrote:

On Thu, Feb 11, 2016 at 12:19 AM, Dmitri Gribenko <gribozavr@gmail.com> > wrote:
> On Thu, Feb 11, 2016 at 12:13 AM, Sergey Kuratov <ksubox.swift@gmail.com> > wrote:
>>>> Can I define similar for my Swift classes ?
>>
>>>No. What would be your use case?
>>
>> I also could have my Swift object with several members, but when send to
>> native part would like to send address exactly one of members.
>> Something like this:
>>
>> // Swift part
>>
>> class ABlock {
>>
>> var channels = 2
>>
>> var samplerate = 44100
>>
>> var buffer : UnsafeMutablePointer<Int16>
>>
>> init() {
>>
>> buffer = UnsafeMutablePointer<Int16>.alloc(2048)
>>
>> }
>>
>> deinit {
>>
>> buffer.dealloc(2048)
>>
>> }
>>
>> }
>>
>>
>> var block = ABlock
>> generate(block) <- here I would like to send address of ABlock.buffer to
>> native part
>>
>> // C part
>> void generate(int16_t *buf) {
>> ...
>> }
>
> I'd recommend to write a Swift wrapper for your C code that accepts
> the class instance, and calls the generate() function with appropriate
> arguments.

Oh, and since your class stores an unsafe pointer (and not an array),
you'd need to call _fixLifetime() on it after the your C function
returns, to ensure that the class instance can't be deallocated before
then. Unless you have other requirements though, I'd recommend just
storing an array though. Then you wouldn't need to care about
_fixLifetime().

Dmitri

--
main(i,j){for(i=2;;i++){for(j=2;j<i;j++){if(!(i%j)){j=0;break;}}if
(j){printf("%d\n",i);}}} /*Dmitri Gribenko <gribozavr@gmail.com>*/


(Jordan Rose) #10

withExtendedLifetime is the function you're looking for.

···

On Feb 11, 2016, at 1:10 , Sergey Kuratov via swift-users <swift-users@swift.org> wrote:

I try to find _fixLifetime in standard library and finally can't :frowning: But function exists in reality and I can call it.
I also found some discussion about https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20151228/005017.html
So as I can understand it's not fixed API to manage scoped life and probably will be changed in the future.

On Thu, Feb 11, 2016 at 5:38 PM, Dmitri Gribenko <gribozavr@gmail.com <mailto:gribozavr@gmail.com>> wrote:
On Thu, Feb 11, 2016 at 12:19 AM, Dmitri Gribenko <gribozavr@gmail.com <mailto:gribozavr@gmail.com>> wrote:
> On Thu, Feb 11, 2016 at 12:13 AM, Sergey Kuratov <ksubox.swift@gmail.com <mailto:ksubox.swift@gmail.com>> wrote:
>>>> Can I define similar for my Swift classes ?
>>
>>>No. What would be your use case?
>>
>> I also could have my Swift object with several members, but when send to
>> native part would like to send address exactly one of members.
>> Something like this:
>>
>> // Swift part
>>
>> class ABlock {
>>
>> var channels = 2
>>
>> var samplerate = 44100
>>
>> var buffer : UnsafeMutablePointer<Int16>
>>
>> init() {
>>
>> buffer = UnsafeMutablePointer<Int16>.alloc(2048)
>>
>> }
>>
>> deinit {
>>
>> buffer.dealloc(2048)
>>
>> }
>>
>> }
>>
>>
>> var block = ABlock
>> generate(block) <- here I would like to send address of ABlock.buffer to
>> native part
>>
>> // C part
>> void generate(int16_t *buf) {
>> ...
>> }
>
> I'd recommend to write a Swift wrapper for your C code that accepts
> the class instance, and calls the generate() function with appropriate
> arguments.

Oh, and since your class stores an unsafe pointer (and not an array),
you'd need to call _fixLifetime() on it after the your C function
returns, to ensure that the class instance can't be deallocated before
then. Unless you have other requirements though, I'd recommend just
storing an array though. Then you wouldn't need to care about
_fixLifetime().

Dmitri

--
main(i,j){for(i=2;;i++){for(j=2;j<i;j++){if(!(i%j)){j=0;break;}}if
(j){printf("%d\n",i);}}} /*Dmitri Gribenko <gribozavr@gmail.com <mailto:gribozavr@gmail.com>>*/

_______________________________________________
swift-users mailing list
swift-users@swift.org
https://lists.swift.org/mailman/listinfo/swift-users