Search code examples
xcodemonoxamarin.iospinvokestatic-libraries

Static library breaks build


I've compiled a static library targetting 'iOS Device' in xcode and have linked it to a monotouch app. When I build and run the app I immediately get an error:

Mono.Debugger.Soft.VMDisconnectedException: Exception of type 'Mono.Debugger.Soft.VMDisconnectedException' was thrown. at Mono.Debugger.Soft.Connection.SendReceive (CommandSet command_set, Int32 command, Mono.Debugger.Soft.PacketWriter packet) [0x00000] in :0 at Mono.Debugger.Soft.Connection.VM_GetVersion () [0x00000] in :0 at Mono.Debugger.Soft.Connection.Connect () [0x00000] in :0 at Mono.Debugger.Soft.VirtualMachine.connect () [0x00000] in :0 at Mono.Debugger.Soft.VirtualMachineManager.ListenInternal (System.Net.Sockets.Socket dbg_sock, System.Net.Sockets.Socket con_sock) [0x00000] in :0

And there is no application output. It doesn't seem to matter if I sign or don't sign the library, I've tried various versions and build settings even switching out between compilers (last compiler I used was the stock GCC 4.2 compiler). Whm

When I build the library for a simulator and link it to the app to run on the device it actually runs on the device, but as soon as a function is p/invoked the app quits and I get system output explaining the pinvoke was unable to be resolved.

The reason this isn't running may be because of build setting or something somewhere , since it runs on the simulator it could be a JIT vs. AOT issue.'

edit:

This is the C# side of things:

        [DllImport("__Internal")]
        private static extern int CreateWorld(b2Vec2 grav, OnIOSContact startContact, ContactOver endContact);

    delegate bool OnIOSContact(MyCollisionEvent ev);
    delegate bool ContactOver(MyCollisionEvent ev);

    [MonoTouch.MonoPInvokeCallback(typeof(OnIOSContact))]
    static bool StatContactStart(MyCollisionEvent ev){...}

    [MonoTouch.MonoPInvokeCallback(typeof(ContactOver))]
    static bool StatContactEnd(MyCollisionEvent ev){...}


    [StructLayout(LayoutKind.Sequential, Size=8),Serializable]
    struct MyCollisionEvent
    {
        public IntPtr ActorA;
        public IntPtr ActorB;
    }




    [StructLayout(LayoutKind.Sequential, Size=8),Serializable]
    public struct b2Vec2
    {
        public b2Vec2(float _x, float _y)
        {
            x = _x;
            y = _y;
        }
        public float x;
        public float y;
    }

and the C code behind it:

       extern "C"
       int CreateWorld(b2Vec2 gravity, bool (*startContact)(Contact), bool (*endContact)(Contact))

 //contact struct to match MyCollisionEvent in C# code
 typedef struct
 {
     b2Body *bodyA;
     b2Body *bodyB;
 }Contact;

/// A 2D column vector.
struct b2Vec2
{
    /// Default constructor does nothing (for performance).
    b2Vec2() {}

    /// Construct using coordinates.
    b2Vec2(float32 x, float32 y) : x(x), y(y) {}

    /// Set this vector to all zeros.
    void SetZero() { x = 0.0f; y = 0.0f; }

    /// Set this vector to some specified coordinates.
    void Set(float32 x_, float32 y_) { x = x_; y = y_; }

    /// Negate this vector.
    b2Vec2 operator -() const { b2Vec2 v; v.Set(-x, -y); return v; }

    /// Read from and indexed element.
    float32 operator () (int32 i) const
    {
        return (&x)[i];
    }

    /// Write to an indexed element.
    float32& operator () (int32 i)
    {
        return (&x)[i];
    }

    /// Add a vector to this vector.
    void operator += (const b2Vec2& v)
    {
        x += v.x; y += v.y;
    }

    /// Subtract a vector from this vector.
    void operator -= (const b2Vec2& v)
    {
        x -= v.x; y -= v.y;
    }

    /// Multiply this vector by a scalar.
    void operator *= (float32 a)
    {
        x *= a; y *= a;
    }

    /// Get the length of this vector (the norm).
    float32 Length() const
    {
        return b2Sqrt(x * x + y * y);
    }

    /// Get the length squared. For performance, use this instead of
    /// b2Vec2::Length (if possible).
    float32 LengthSquared() const
    {
        return x * x + y * y;
    }

    /// Convert this vector into a unit vector. Returns the length.
    float32 Normalize()
    {
        float32 length = Length();
        if (length < b2_epsilon)
        {
            return 0.0f;
        }
        float32 invLength = 1.0f / length;
        x *= invLength;
        y *= invLength;

        return length;
    }

    /// Does this vector contain finite coordinates?
    bool IsValid() const
    {
        return b2IsValid(x) && b2IsValid(y);
    }

    float32 x, y;
};

Edit 2:

I should have mentioned this when I first wrote the post but I have been able to get the app running on the device a few times. Typically it involved revuilding the project/library with slightly different build settings (such as signing the library) but I haven't been able to discern the steps needed to be taken which causes these successful builds...

Each time it did run it crashed out (due to unrelated bugs) but even slight modification to code (such as commenting out a line) caused the same error to pop up again. Even restoring the line wouldn't make the error go away.


Solution

  • After much pain I decided I'd do a clean install of iOS on the iPhone and that fixed up the errors. I'm still not quite sure what was causing the errors but since a clean iOS install fixed it I can only assume it had something to do with the previous install and was hopefully very specific to that one install.