`asCContext::CallScriptFunction` called with null

Started by
4 comments, last by Chisser98 5 years, 4 months ago

Hello,

I have run into a bit of an issue that I uncovered when trying to import a shared interface into another module.

More specifically, when I attempt to import my shared interface, I am getting an Access violation error on line 1748 of as_context.cpp. The function is `asCContext::CallScriptFunction`, and it looks like the parameter `asCScriptFunction *func` is null.

The interesting thing is that if I remove the import of the shared interface into the module, the code works fine. I am using this shared interface in my main module, and have not yet started using it in my other modules.

The code that I am building my shared module with looks like this:


external shared interface IPlayer;

The IPlayer code looks like this:


#include "IModel.as"

shared interface IPlayer : IKeyboardEventListener, IMouseMotionEventListener, IMouseButtonEventListener, IMouseWheelEventListener, IModel
{
    array<Entity> selectedUnits() const;
    void setSelectedUnits(const array<Entity>& in units);

    bool owner(const Entity entity) const;
    bool owner(const IGameObject@ gameObject) const;

    uint32 totalCredits() const;
    uint32 totalPopulation() const;
    uint32 totalFood() const;
    uint32 totalMinerals() const;

    uint32 numUnits() const;
    uint32 numBuildings() const;

    uint32 id() const;
    const string& name() const;

    void placeBuilding(Entity entity);
}

mixin class PlayerMixin
{
    protected uint32 totalCredits_ = 0;
    protected uint32 totalPopulation_ = 0;
    protected uint32 totalFood_ = 0;
    protected uint32 totalMinerals_ = 0;

    protected uint32 id_ = 0;
    protected string name_;

    bool owner(const Entity entity) const
    {
        const auto scriptObjectComponent = entity.componentScriptObjectComponent();

        if (bool(scriptObjectComponent) && scriptObjectComponent.get().scriptObjectHandle)
        {
            const auto gameObject = cast<IGameObject>(scriptObjectComponent.get().scriptObjectHandle.get());

            if (gameObject !is null) return owner(gameObject);
        }

        return false;
    }

    bool owner(const IGameObject@ gameObject) const
    {
        auto unit = cast<IUnit>(gameObject);
        if (unit !is null)
        {
            return unit.owner() == @this;
        }
        else
        {
            auto building = cast<IBuilding>(gameObject);
            if (building !is null) return building.owner() == @this;
        }

        return false;
    }

    uint32 totalCredits() const
    {
        return totalCredits_;
    }

    uint32 totalPopulation() const
    {
        return totalPopulation_;
    }

    uint32 totalFood() const
    {
        return totalFood_;
    }

    uint32 totalMinerals() const
    {
        return totalMinerals_;
    }

    uint32 id() const
    {
        return id_;
    }

    const string& name() const
    {
        return name_;
    }
}


IModel looks like this:


#include "IChangeListener.as"

shared interface IModel
{
    void tick(const float delta);
    void addChangeListener(IChangeListener@ changeListener);
    void removeChangeListener(IChangeListener@ changeListener);
}

mixin class ModelMixin
{
    private array<IChangeListener@> changeListeners_;

    void tick(const float delta)
    {
    }

    void addChangeListener(IChangeListener@ changeListener)
    {
        println("adding change listener");
        changeListeners_.push_back(changeListener);
    }

    void removeChangeListener(IChangeListener@ changeListener)
    {
        for (uint i=0; i < changeListeners_.size(); i++)
        {
            if (@changeListeners_[i] == @changeListener)
            {
                changeListeners_.removeAt(i);
                break;
            }
        }
    }

    protected void updateChangeListeners()
    {
        for (uint i=0; i < changeListeners_.size(); i++)
        {
            changeListeners_[i].update();
        }
    }
}

 

IChangeListener looks like this:


shared interface IChangeListener
{
    void update();
}

 

Another way I have found to fix the issue is to make the IPlayer interface not inherit from IModel, and instead copy the definitions from IModel directly into IPlayer.

I have been able to reproduce this in version 2.32.0, as well as the latest from SVN.

Advertisement

Hello,

I have been able to reproduce this in a minimal code example. If I build module one with the following code:


shared interface Interface1
{
    void test();
}

shared interface Interface2 : Interface1
{
}

class Object : Interface2
{
    void test()
    {
    }
}

void main()
{
    Object@ object = Object();
    object.test();
}

And then build module two with the following code:


external shared interface Interface2;

This triggers the following assertion: Assertion failed: func->objectType == intfType, file c:\users\jarrett\projects\angelscript\sdk\angelscript\source\as_builder.cpp, line 2754

This is with the latest code from SVN.

Thanks for the detailed report and for finding the minimal code to reproduce the problem.

I'll investigate and have this fixed as soon as possible.

 

AngelCode.com - game development and more - Reference DB - game developer references
AngelScript - free scripting library - BMFont - free bitmap font generator - Tower - free puzzle game

Fixed in revision 2569.

Regards,
Andreas

AngelCode.com - game development and more - Reference DB - game developer references
AngelScript - free scripting library - BMFont - free bitmap font generator - Tower - free puzzle game

Awesome, thanks Andreas!

This topic is closed to new replies.

Advertisement