Problems exposing C++ functions to Blueprints

Hi all!

I have this C++ code:

MappingsHelper.h



// Fill out your copyright notice in the Description page of Project Settings.

#pragma once

#include "Components/ActorComponent.h"
#include "MappingsHelper.generated.h"


UCLASS( ClassGroup=(Custom), meta=(BlueprintSpawnableComponent))
class VERTICALSPACESHOOTER_API UMappingsHelper : public UActorComponent
{
	GENERATED_BODY()

private:
    int32 actions;
    TArray<FName> actionNames;
   
public:	
	// Sets default values for this component's properties
	UMappingsHelper();

	// Called when the game starts
	virtual void InitializeComponent() override;
	
	// Called every frame
	virtual void TickComponent( float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction ) override;

    UFUNCTION(BlueprintCallable, Category = "Mappings Helper")
    TArray<FName> GetActionNames();

    UFUNCTION(BlueprintCallable, Category = "Mappings Helper")
    int32 GetActionsNumber();
};


MappingsHelper.cpp



// Fill out your copyright notice in the Description page of Project Settings.

#include "VerticalSpaceShooter.h"
#include "MappingsHelper.h"


// Sets default values for this component's properties
UMappingsHelper::UMappingsHelper()
{
	// Set this component to be initialized when the game starts, and to be ticked every frame.  You can turn these features
	// off to improve performance if you don't need them.
	bWantsInitializeComponent = true;
	PrimaryComponentTick.bCanEverTick = true;

	// ...
}


// Called when the game starts
void UMappingsHelper::InitializeComponent()
{
	Super::InitializeComponent();

	// ...

    actions = 0;
    actionNames = TArray<FName>();

    if (GetOwner()->InputComponent != NULL)
    {
        /*actions = GetOwner()->InputComponent->GetNumActionBindings();

        if (actions > 0)
        {
            for (int32 a = 0; a < actions; a++)
            {
                actionNames.Add(GetOwner()->InputComponent->GetActionBinding(a).ActionName);
            }
        }*/
    }
}


// Called every frame
void UMappingsHelper::TickComponent( float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction )
{
	Super::TickComponent( DeltaTime, TickType, ThisTickFunction );

	// ...
}


TArray<FName> UMappingsHelper::GetActionNames()
{
    return actionNames;
}


int32 UMappingsHelper::GetActionsNumber()
{
    return actions;
}


As i noticed there was nothing to get access to the mappings from the blueprint system, i decided to write a little helper, but i have two problems, one major and one minor:

The minor problem is… that i don’t know how to refresh the exposed functions in the blueprint editor.
I save all files in VS2013 Community (i have the UnrealVS extension), compile the solution, and… some times i get the new functions in the blueprint editor… and sometimes not :S.

The major problem is, this commented part:



 /*actions = GetOwner()->InputComponent->GetNumActionBindings();

        if (actions > 0)
        {
            for (int32 a = 0; a < actions; a++)
            {
                actionNames.Add(GetOwner()->InputComponent->GetActionBinding(a).ActionName);
            }
        }*/


If i uncomment it, i get ALWAYS an AccessViolation error when i call GetNumActionBindings function.
The MappingHelper component is attached to a Pawn and i call the GetActionNames method from its blueprint.

I’m using the 4.7.2 version of the engine.

Excuse me if my english is not good :slight_smile: .

See ya!

For the Major:
You already debugged it and GetOwner() and InputComponent are not NULL?
Make sure to use




if(GetOwner()){...}



In cases of Access Violations (most the time Nullpointer references) this helps alot. And should be done anyway to make the code stable.

For the Minor:
Never had any problems with it. Maybe it depends on the mode you use. I am using DebugEditor for compiling and it works fine more me.

Yes, i did the check:



// Called when the game starts
void UMappingsHelper::InitializeComponent()
{
	Super::InitializeComponent();

	// ...

    actions = 0;
    actionNames = TArray<FName>();

    **if (GetOwner()->InputComponent != NULL)**
    {
        /*actions = GetOwner()->InputComponent->GetNumActionBindings();

        if (actions > 0)
        {
            for (int32 a = 0; a < actions; a++)
            {
                actionNames.Add(GetOwner()->InputComponent->GetActionBinding(a).ActionName);
            }
        }*/
    }
}


I’ll try compiling with DebugEditor.

See ya!

If you are compiling in DebugEditor, set a breakpoint in this function and go step by step.
Then you can find out where the access violation occures.