Unresolved external when calling static function pointer

I’m trying to do an implementation of this library for demuxing MP4 data as an Unreal third party plug-in. To try and get it working, I’ve been trying to implement the test code found here as a c++ actor component. The problem I’m running into is the use of a static function pointer. When building, I get an unresolved external symbol on the only line that uses it. This builds fine when I comment out the one line but then obviously it doesn’t work.
This is the function in question as written in Unreal:

static int read_callback(int64_t offset, void *buffer, size_t size, void *token)
{
	UTestMiniMP4::FINPUT_BUFFER *buf = (UTestMiniMP4::FINPUT_BUFFER*)token;
	size_t to_copy = MINIMP4_MIN(size, buf->size - offset - size);
	memcpy(buffer, buf->buffer + offset, to_copy);
	return to_copy != size;
}

and this is how it is called:

    MP4D_open(&mp4, read_callback, &buf, input_size);

any ideas on how I can fix this?

Hello! Unresolved external means that linker cant find defenition, can you share full error code?

No error code given from my log but I’ll share a screenshot!

I do define MINIMP4_IMPLEMENTATION at the top of my test class’s h file. Without that, ALL calls to functions in minimp4.h get an unresolved external symbol, which makes sense. I’m just confused as to why the one function is getting the error.

Linkage error is due to object files not being able to find the symbols needed. Seems like you might have forgotten including some library which holds definitions you need.

Could you do two things for me, post both the include of the .cpp and .h files of the class in question as-well as an actual screenshot of the macro you mentioned, MINIMP4_IMPLEMENTATION.

Also, maybe post your c# build-file, maybe some dependency that you need hasn’t been included.

Re-reading the error, it clearly states that the ‘MP4D_open’ function is the issue and not MINIMP4_IMPLEMENTATION.
Could you first make sure you have actually included the code for MP4D_open when porting this MP4 project?

The library is a single header file, [this the code for MP4D_open.][1]

I define MINIMP4_IMPLEMENTATION at the top of my class’s h file:

345478-define-capture.png

this is the build.cs of the library as a third party plugin:

using UnrealBuildTool;
using System.IO;
using System.Collections.Generic;

public class MiniMP4 : ModuleRules
{
    public MiniMP4(ReadOnlyTargetRules Target) : base(Target)
    {
        Type = ModuleType.External;

        string IncludePath = System.IO.Path.Combine(ModuleDirectory, "include");
        PublicIncludePaths.Add(IncludePath);
    }
}

and this is the build.cs of the game module:

// Copyright Epic Games, Inc. All Rights Reserved.

using UnrealBuildTool;

public class UnrealMiniMp4 : ModuleRules
{
	public UnrealMiniMp4(ReadOnlyTargetRules Target) : base(Target)
	{
		PCHUsage = PCHUsageMode.UseExplicitOrSharedPCHs;

        PublicDependencyModuleNames.AddRange(new string[] { "Core", "CoreUObject", "Engine", "InputCore", "HTTP", "MiniMP4"});

		PrivateDependencyModuleNames.AddRange(new string[] {  });

		// Uncomment if you are using Slate UI
        // PrivateDependencyModuleNames.AddRange(new string[] { "Slate", "SlateCore" });

        // Uncomment if you are using online features
        // PrivateDependencyModuleNames.Add("OnlineSubsystem");

        // To include OnlineSubsystemSteam, add it to the plugins section in your uproject file with the Enabled attribute set to true
    }
}

Ok then I have yet another question as you are only giving bits and pieces of your code makes it hard to judge the scope of some things; Such as, the static callback function you’ve defined, is that an inlined function inside of a class definition or is it a global function (as in not defined within a namespace or class-definition)?

Let’s assume the former, then the issue you are seeing could be due to the namespace mangling the callback type making it dependent on the namespace.

I’m very sorry, I just didn’t want to flood the post with my code :). You’re right, its outside of any namespace or class definition. If it makes things easier, here is the code for my class:

Header file:

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

#include "CoreMinimal.h"

#include <embree2/rtcore.h>

#include "Components/ActorComponent.h"
#include "Runtime/Online/HTTP/Public/Http.h"
#include "TestMiniMP4.generated.h"

#define MINIMP4_MIN(x, y) ((x) < (y) ? (x) : (y))

UCLASS( ClassGroup=(Custom), meta=(BlueprintSpawnableComponent) )
class UNREALMINIMP4_API UTestMiniMP4 : public UActorComponent
{

	public: struct FINPUT_BUFFER
	{
		uint8_t *buffer;
		ssize_t size;
	};
	
	GENERATED_BODY()

public:	
	// Sets default values for this component's properties
	UTestMiniMP4();

	void FetchVideo (FString _url);
	void OnVideoResponseRecieved(FHttpRequestPtr Request, FHttpResponsePtr Response, bool wasSuccessful);
	int demux(uint8_t *input_buf, ssize_t input_size, int ntrack);

protected:
	// Called when the game starts
	virtual void BeginPlay() override;

public:	
	// Called every frame
	virtual void TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction) override;

		
};

I’ll post the cpp in a seperate reply due to character limits

Can’t post the cpp file due to character limits but here is the relevant code I think:

// Fill out your copyright notice in the Description page of Project Settings.
#include "TestMiniMP4.h"

#define MINIMP4_IMPLEMENTATION
#include "minimp4.h"


static int read_callback(int64_t offset, void *buffer, size_t size, void *token)
{
	UTestMiniMP4::FINPUT_BUFFER *buf = (UTestMiniMP4::FINPUT_BUFFER*)token;
	size_t to_copy = MINIMP4_MIN(size, buf->size - offset - size);
	memcpy(buffer, buf->buffer + offset, to_copy);
	return to_copy != size;
}




int UTestMiniMP4::demux(uint8_t* input_buf, ssize_t input_size, int ntrack)
{
	//FILE* fout;
	const char* p = new char;
	int /*ntrack, *//*i,*/ spspps_bytes;
	size_t i;
    const void *spspps;
    FINPUT_BUFFER buf = { input_buf, input_size };
    MP4D_demux_t mp4 = { 0, };
    MP4D_open(&mp4, read_callback, &buf, input_size);
}