Download

js/c++ communication

I apologize if this is something obvious I missed, but I can’t find out how to make c++ functions callable from javascript.
I tried using EMSCRIPTEN_KEEPALIVE as I can’t pass command line arguments to emscripten without recompiling the engine, but <emscripten.h> can’t be found when included and cheating by adding


#ifndef EMSCRIPTEN_KEEPALIVE
#define EMSCRIPTEN_KEEPALIVE
#endif

still results in the function name being unknown from js.
For completeness, the entire header:



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

#pragma once
#ifndef EMSCRIPTEN_KEEPALIVE
//#include "emscripten.h"
#define EMSCRIPTEN_KEEPALIVE
#endif
#include "Components/ActorComponent.h"
#include "ColorChangingThing.generated.h"


UCLASS( ClassGroup=(Custom), meta=(BlueprintSpawnableComponent) )
class HTML5_COM_TEST_API UColorChangingThing : public UActorComponent
{
	GENERATED_BODY()

public:	
	UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "ColorChangingActor")
		FVector color = FVector(0,0,0);
	// Sets default values for this component's properties
	UColorChangingThing();

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

	
	
};

EMSCRIPTEN_KEEPALIVE
void changeAllColours(float r, float g, float b);

//using namespace emscripten;

/*EMSCRIPTEN_BINDINGS(my_module) {
	function("changeAllColours", &changeAllColours);
}*/


So I’ve found a possible but unsatisfactory solution.

I’ve downloaded and changes the engine to change some arguments when calling emscripten. Specifically, in HTML5ToolChain.cs, I’ve changed the line



Result += " -s EXPORTED_FUNCTIONS=\"'_main', '_resize_game', '_on_fatal']\"";


to



Result += " -s EXPORTED_FUNCTIONS=\"'_main', '_resize_game', '_on_fatal', '_changeAllColors']\"";


And wrapped the function in the header in extern “c”, like so (I’d forgotten that, oops):



extern "C" {
	void changeAllColors(float r, float g, float b);
}


However I don’t think it’s good practice to change the engine whenever a new function needs to be visible from js.
I could edit the engine further to make exported functions a setting, but I can’t help but feel I’ve missed something easier. For one, I haven’t been able to include the emscripten headers used by the engine, they are not found even after setting include path in Visual Studio, and have thus been unable to use its macro’s. I’ll try some more things and report back, in the meantime any help is duly appreciated.

So looking back at the emscripten tutorial I realized what the correct solution should be:



#ifdef __EMSCRIPTEN__
#include <emscripten.h>
#endif

...]

extern "C" {
#ifdef __EMSCRIPTEN__
	EMSCRIPTEN_KEEPALIVE
#endif
	void changeAllColors(float r, float g, float b);
}


In other words: wrap the emstripten-specific code in macro checks and everything will be fine.

Just a quick question, are you trying to access the emscripten generated code outside of the project, in your html5/js app or are you using this inside the project?

outside, in the js app. Why?

Oh i was just curious what its for. I was looking for something similar a few months ago. :slight_smile:

Ah, well in that case, my company creates product configuration and visualisation software. We were interested to see if we could use UE4 to improve graphics quality. To support legacy client catalogs and applications it was necessary to call certain functions from js.