CSharp bindings, delegates and GC


A couple of questions to @Viv and @Krishna, since you’ve been working on these repos.

I have implemented a variation of the SafeMessages app (basically just copying the principles, just changing high level flows and types), and the native bindings I more or less copy pasted from the CSharp bindings repo, with just a few additions and indenting adjustments and such.

As might have seen from my previous posts here, I’ve had these problems since the very first time I started with this (October last year), but I haven’t really understood what was going on. At least some of it is getting clearer to me now that I went back to NetFramework 4.x instead of NetCore, simply because the managed debugging assistant now gave me some more information when the errors happened (wow… if only I had known this before).

When I run the app as it is, the garbage collector pulls the rug on these variables, while they are still in use.
So, as you would probably already have guessed, this is because we’ve passed this along to the unmanaged code, and let the the variables in the managed code go out of scope. Then later on the callback we access these members by pointer reference and try to cast it to the ClrType. But at that point they are GC:d.

Managed Debugging Assistant 'CallbackOnCollectedDelegate' 
A callback was made on a garbage collected delegate of type 'SAFEEventStore.NetFramework!SAFE.DotNET.Native.CipherOptFreeCb::Invoke'. This may cause application crashes, corruption and data loss. When passing delegates to unmanaged code, they must be kept alive by the managed application until it is guaranteed that they will never be called.

I don’t usually work with transitions to unmanaged code, so this is not an area I’m very familiar with. But when I looked around, it seems that GCHandle.Alloc as seen here in safe_app_csharp is supposed to add a reference to the delegate, which prevents the GC from collecting it.

So I wonder, did you not experience that the callback delegate instances have become garbage collected after a short while?
Is there anything we can do here to avoid this?
I’m trying to look at it and understand what needs to be done, but as I said, I’m not very familiar with transition between managed and unmanaged so I basically need reading up on the whole subject before being able to tackle it properly.

Thanks alot!


There are drastic changes in the branch that I am working on right now compared to the master branch. I ll share the WIP branch here. The tests are passing right now.

Once you have a look at the branch you will be able to understand, how the support for more platforms are added. I have run the Core and Framework tests to confirm they work. Also, integrated the bindings with the mobile apps and tested on Android. Testing on iOS is alone pending. Once it is tested and confirmed on iOS then we will be able to get it merged to the upstream at the earliest and also publish in Nuget.


Sure has happened a lot there! Nice to see.
I’ll be digging in to this on my few spare moments, and eventually I can check if I can reproduce the above errors. Beginning to wonder if my environment is askew somehow, but I’ll get to that too. A long list of things to try now :slight_smile: