Re: C++ pointer to Cocoa object

2018-09-10 Thread Alastair Houghton
On 8 Sep 2018, at 15:32, Casey McDermott  wrote:
> 
>>> If you are using ARC and want to get a strong
> reference on the object, you have to use __bridge_retained
> 
> That is handy to know!  I see there is also __bridge_transfer to go the other 
> way.

IMO the Core Foundation wrappers CFBridgingRetain( ) and CFBridgingRelease() 
are slightly easier to follow in code; I’ve never been a huge fan of having 
lots of double-underscore things floating about.

Kind regards,

Alastair.

--
http://alastairs-place.net

___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: C++ pointer to Cocoa object

2018-09-08 Thread Casey McDermott
>> If you are using ARC and want to get a strong
 reference on the object, you have to use __bridge_retained

That is handy to know!  I see there is also __bridge_transfer to go the other 
way.

In this case we put the Cocoa controls into a NSView, which releases them.
The NSView deletes our LView, which deletes the C++ controls.

Thanks,

Casey McDermott
www.TurtleSoft.com
___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: C++ pointer to Cocoa object

2018-09-08 Thread Jean-Daniel


> Le 7 sept. 2018 à 19:46, Casey McDermott  a écrit :
> 
> We need to link some of our C++ classes to a matching Cocoa class.
> It's easy for Cocoa to reference C++ objects.  Going the other way is harder.
> 
> We have been using a linker class that has a void pointer to the Obj-C object
> in the C++ header.  We then cast it to a Cocoa object in the Obj-C++ source.
> For example, in the C++ header we have:
> 

How are you setting the pointer ? If you are using ARC and want to get a strong 
reference on the object, you have to use __bridge_retained, which tell ARC to 
keep the reference valid.
Once you are done with the objc object, you have to release it.

> void *mCocoaPopupPtr = nil;
> 
> Then in the source:
> 
> void GSCocoaPopupLinker::setCocoaFieldVisible(const BOOL inValue)
> {
>   if (mCocoaPopupPtr != nil)
>   {
>   GSPopupButton *cocoaPopup = (__bridge GSPopupButton 
> *)mCocoaPopupPtr;
>   [cocoaPopup setHidden : !inValue];
>   }
> }
> 
> Problem is, with ARC turned on, the pointer is never nil, so it crashes.  
> The void pointer somehow becomes an NSAtom instead of 0.
> 
> There's very little documentation on NSAtom, but it appears to be Apple's way 
> to 
> use the excess bits in a 64-bit address to store class info. 
> 
> Is there some other way to test for an invalid void pointer?
> 
> Thanks,
> 
> Casey McDermott
> TurtleSoft.com
> ___
> 
> Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)
> 
> Please do not post admin requests or moderator comments to the list.
> Contact the moderators at cocoa-dev-admins(at)lists.apple.com
> 
> Help/Unsubscribe/Update your Subscription:
> https://lists.apple.com/mailman/options/cocoa-dev/mailing%40xenonium.com
> 
> This email sent to mail...@xenonium.com

___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: C++ pointer to Cocoa object

2018-09-07 Thread Casey McDermott
>>  NSAtom is a red herring

Quite possible.

Usually we create the C++ object, which constructs a linker in the next line or 
two.
Then that creates the Cocoa object in the next line or two and hooks them up.  
They all stick around until all are deleted.  Not much chance for object 
lifetime problems.

This error happened when I accidentally put something after the linker was made,
but before it made the Cocoa object.  It's probably the first time the nil test 
has even 
happened on a nil pointer to a Cocoa object.

Unfortunately that specific error is now fixed several times over, and I didn't 
commit 
when it was breaking.  But if it happens again I'll do more in-depth testing on 
it.

Thanks,

Casey McDermott
www.TurtleSoft.com
___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: C++ pointer to Cocoa object

2018-09-07 Thread Alex Zavatone
I ran into this while writing wrappers for pjsip in C++ to Obj-C and vice versa.

The only conclusion that I came to was to store what the valid pointer value 
was after it was created.  The failure cases could be an undefined or out of 
range pointer but they proved not easily able to test for.  All I could 
reliably test for was a known good pointer value, so that’s what I did.

What I did was assume that if a wrapping Obj-C class which allocated the C++ 
object was valid, that the C++ object was valid and then store the pointer 
values.  If at any time the pointers changed I could not assume that they were 
pointing to a valid location, so recreate the C++ object again and store the 
new pointers.  It worked.

IIRC, I think I also passed in a weak reference to the Obj-C class so that the 
C++ functions could access the container.  Passing data back and forth by 
casting was a little tricky.  I can look at what we did to work with this this 
when I get back home

I’m sure it’s not best, but it never crashed for us.  I would love to hear more 
of a real solution if anyone has one.

Hope this helps.

Alex

Sent from my iPhone

> On Sep 7, 2018, at 12:46 PM, Casey McDermott  wrote:
> 
> We need to link some of our C++ classes to a matching Cocoa class.
> It's easy for Cocoa to reference C++ objects.  Going the other way is harder.
> 
> We have been using a linker class that has a void pointer to the Obj-C object
> in the C++ header.  We then cast it to a Cocoa object in the Obj-C++ source.
> For example, in the C++ header we have:
> 
> void *mCocoaPopupPtr = nil;
> 
> Then in the source:
> 
> void GSCocoaPopupLinker::setCocoaFieldVisible(const BOOL inValue)
> {
>if (mCocoaPopupPtr != nil)
>{
>GSPopupButton *cocoaPopup = (__bridge GSPopupButton *)mCocoaPopupPtr;
>[cocoaPopup setHidden : !inValue];
>}
> }
> 
> Problem is, with ARC turned on, the pointer is never nil, so it crashes.  
> The void pointer somehow becomes an NSAtom instead of 0.
> 
> There's very little documentation on NSAtom, but it appears to be Apple's way 
> to 
> use the excess bits in a 64-bit address to store class info. 
> 
> Is there some other way to test for an invalid void pointer?
> 
> Thanks,
> 
> Casey McDermott
> TurtleSoft.com
> ___
> 
> Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)
> 
> Please do not post admin requests or moderator comments to the list.
> Contact the moderators at cocoa-dev-admins(at)lists.apple.com
> 
> Help/Unsubscribe/Update your Subscription:
> https://lists.apple.com/mailman/options/cocoa-dev/zav%40mac.com
> 
> This email sent to z...@mac.com
___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: C++ pointer to Cocoa object

2018-09-07 Thread Greg Parker

> On Sep 7, 2018, at 3:48 PM, Jens Alfke  wrote:
> 
>> On Sep 7, 2018, at 10:46 AM, Casey McDermott  wrote:
>> 
>> Problem is, with ARC turned on, the pointer is never nil, so it crashes.  
>> The void pointer somehow becomes an NSAtom instead of 0.
> 
> Something wrote to that pointer, then. If you initialize it to nullptr, it 
> will stay that way. NSAtom is a red herring — probably the mCocoaPopupPtr was 
> pointing to a valid object, but it got freed, and there is now (by chance) an 
> NSAtom instance residing at that address.

NSAtom is one of the tagged pointer object classes. On 64-bit macOS, if you 
have an address whose lowest four bits are 0x…1, and you use it as if it were 
an Objective-C object, then it will be an NSAtom. (Same for 64-bit iOS, except 
with an address that starts with 0x8….)

Nothing in the OS actually uses class NSAtom. (We're trying to get rid of it 
but there are some binary compatibility problems.) Instead of "pointer variable 
somehow becomes an NSAtom" you should be looking for "pointer variable somehow 
has a random or uninitialized value". For example, if the object that contains 
this mCocoaPopupPtr field were itself deallocated then a use-after-free could 
cause this symptom.


>> Is there some other way to test for an invalid void pointer?

There is no way to programmatically distinguish all valid Objective-C object 
pointers from all invalid ones. It's just like C and C++ in that respect.


-- 
Greg Parker gpar...@apple.com  Runtime 
Wrangler


___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: C++ pointer to Cocoa object

2018-09-07 Thread Jens Alfke


> On Sep 7, 2018, at 10:46 AM, Casey McDermott  wrote:
> 
> Problem is, with ARC turned on, the pointer is never nil, so it crashes.  
> The void pointer somehow becomes an NSAtom instead of 0.

Something wrote to that pointer, then. If you initialize it to nullptr, it will 
stay that way. NSAtom is a red herring — probably the mCocoaPopupPtr was 
pointing to a valid object, but it got freed, and there is now (by chance) an 
NSAtom instance residing at that address.

The reason the object got freed is probably that your C++ pointer isn't known 
to ARC so it didn't bump the refcount of the object assigned to it. You'll need 
to use CFRetain/CFRelease to manually retain objects assigned to that pointer.

—Jens
___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: C++ pointer to Cocoa object

2018-09-07 Thread Saagar Jha
Usually the way you get an NSAtom is because you’re reading garbage–either 
somebody scribbled over your pointer or it was garbage to begin with. Does 
mCocoaPopupPtr ever get set to nil? Does it have a consistent value? What 
happens if you run with the Address Sanitizer enabled, or with NSZombieEnabled 
set?

Saagar Jha

> On Sep 7, 2018, at 10:46, Casey McDermott  wrote:
> 
> We need to link some of our C++ classes to a matching Cocoa class.
> It's easy for Cocoa to reference C++ objects.  Going the other way is harder.
> 
> We have been using a linker class that has a void pointer to the Obj-C object
> in the C++ header.  We then cast it to a Cocoa object in the Obj-C++ source.
> For example, in the C++ header we have:
> 
> void *mCocoaPopupPtr = nil;
> 
> Then in the source:
> 
> void GSCocoaPopupLinker::setCocoaFieldVisible(const BOOL inValue)
> {
>   if (mCocoaPopupPtr != nil)
>   {
>   GSPopupButton *cocoaPopup = (__bridge GSPopupButton 
> *)mCocoaPopupPtr;
>   [cocoaPopup setHidden : !inValue];
>   }
> }
> 
> Problem is, with ARC turned on, the pointer is never nil, so it crashes.  
> The void pointer somehow becomes an NSAtom instead of 0.
> 
> There's very little documentation on NSAtom, but it appears to be Apple's way 
> to 
> use the excess bits in a 64-bit address to store class info. 
> 
> Is there some other way to test for an invalid void pointer?
> 
> Thanks,
> 
> Casey McDermott
> TurtleSoft.com
> ___
> 
> Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)
> 
> Please do not post admin requests or moderator comments to the list.
> Contact the moderators at cocoa-dev-admins(at)lists.apple.com
> 
> Help/Unsubscribe/Update your Subscription:
> https://lists.apple.com/mailman/options/cocoa-dev/saagar%40saagarjha.com
> 
> This email sent to saa...@saagarjha.com

___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: C++ pointer to Cocoa object

2018-09-07 Thread James Walker

On 9/7/18 10:46 AM, Casey McDermott wrote:

We need to link some of our C++ classes to a matching Cocoa class.
It's easy for Cocoa to reference C++ objects.  Going the other way is harder.

We have been using a linker class that has a void pointer to the Obj-C object
in the C++ header.  We then cast it to a Cocoa object in the Obj-C++ source.
For example, in the C++ header we have:

void *mCocoaPopupPtr = nil;

Then in the source:

void GSCocoaPopupLinker::setCocoaFieldVisible(const BOOL inValue)
{
if (mCocoaPopupPtr != nil)
{
GSPopupButton *cocoaPopup = (__bridge GSPopupButton 
*)mCocoaPopupPtr;
[cocoaPopup setHidden : !inValue];
}
}

Problem is, with ARC turned on, the pointer is never nil, so it crashes.
The void pointer somehow becomes an NSAtom instead of 0.

There's very little documentation on NSAtom, but it appears to be Apple's way to
use the excess bits in a 64-bit address to store class info.

Is there some other way to test for an invalid void pointer?



I don't use ARC, so I'm just speculating here, but maybe a solution 
would be to use the private implementation pattern.  That is, in your 
public C++ header, the only member would look like


std::unique_ptr< MyClassImp > _imp;

MyClassImp would be declared and defined only in the Objective-C++ 
source file (except for a forward declaration in the C++ header), so it 
could use proper Objective-C types as members.


___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: C++ pointer to Cocoa object

2018-09-07 Thread Gary L. Wade
You might also find WWDC 2018, Session 409, informative.
--
Gary L. Wade
http://www.garywade.com/

> On Sep 7, 2018, at 1:44 PM, Allan Odgaard  wrote:
> 
>> On 7 Sep 2018, at 19:46, Casey McDermott wrote:
>> 
>> Problem is, with ARC turned on, the pointer is never nil, so it crashes.
>> The void pointer somehow becomes an NSAtom instead of 0.
> 
> Nil is nil, I think your issue is rather that you do not properly retain the 
> pointer before storing it as void*.

___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: C++ pointer to Cocoa object

2018-09-07 Thread Allan Odgaard

On 7 Sep 2018, at 19:46, Casey McDermott wrote:

Problem is, with ARC turned on, the pointer is never nil, so it 
crashes.

The void pointer somehow becomes an NSAtom instead of 0.


Nil is nil, I think your issue is rather that you do not properly retain 
the pointer before storing it as void*.

___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


C++ pointer to Cocoa object

2018-09-07 Thread Casey McDermott
We need to link some of our C++ classes to a matching Cocoa class.
It's easy for Cocoa to reference C++ objects.  Going the other way is harder.

We have been using a linker class that has a void pointer to the Obj-C object
in the C++ header.  We then cast it to a Cocoa object in the Obj-C++ source.
For example, in the C++ header we have:

void *mCocoaPopupPtr = nil;

Then in the source:

void GSCocoaPopupLinker::setCocoaFieldVisible(const BOOL inValue)
{
if (mCocoaPopupPtr != nil)
{
GSPopupButton *cocoaPopup = (__bridge GSPopupButton 
*)mCocoaPopupPtr;
[cocoaPopup setHidden : !inValue];
}
}

Problem is, with ARC turned on, the pointer is never nil, so it crashes.  
The void pointer somehow becomes an NSAtom instead of 0.

There's very little documentation on NSAtom, but it appears to be Apple's way 
to 
use the excess bits in a 64-bit address to store class info. 

Is there some other way to test for an invalid void pointer?

Thanks,

Casey McDermott
TurtleSoft.com
___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com