Error: unknown type name 'USTRUCT'

I have my unreal plugin working and now i want to extend it with my own custom blueprint class. My plugin and blueprint are generated by another script, which spits out a .h and .cpp file, but in a format different from the unreal blueprint examples, most of the generated code is put into the .cpp file. I noticed that the unreal build tool chain expects class’es to be defined in the public header, with special macros, and not the private .cpp file. Is it possible to just generate the .cpp file, and skip the header?

[1/3] Compile Module.MyPlugin.cpp
In file included from /home/raptor/Documents/Unreal Projects/MyProject/Plugins/MyPlugin/Intermediate/Build/Linux/B4D820EA/UE4Editor/Development/MyPlugin/Module.MyPlugin.cpp:2:
/home/raptor/Documents/Unreal Projects/MyProject/Plugins/MyPlugin/Source/MyPlugin/Private/MyPlugin.cpp:335:1: error: unknown type name 'USTRUCT'
USTRUCT(BlueprintType)
^
/home/raptor/Documents/Unreal Projects/MyProject/Plugins/MyPlugin/Source/MyPlugin/Private/MyPlugin.cpp:335:23: error: expected ';' after top level declarator
USTRUCT(BlueprintType)
                      ^
                      ;
/home/raptor/Documents/Unreal Projects/MyProject/Plugins/MyPlugin/Source/MyPlugin/Private/MyPlugin.cpp:337:2: error: C++ requires a type specifier for all declarations
        GENERATED_USTRUCT_BODY()
        ^
/home/raptor/Documents/Unreal Projects/MyProject/Plugins/MyPlugin/Source/MyPlugin/Private/MyPlugin.cpp:337:26: error: expected ';' at end of declaration list
        GENERATED_USTRUCT_BODY()
                                ^
                                ;
/home/raptor/Documents/Unreal Projects/MyProject/Plugins/MyPlugin/Source/MyPlugin/Private/MyPlugin.cpp:340:13: error: C++ requires a type specifier for all declarations
                UPROPERTY(EditAnywhere, Category=Triangle)
                          ^
/home/raptor/Documents/Unreal Projects/MyProject/Plugins/MyPlugin/Source/MyPlugin/Private/MyPlugin.cpp:340:27: error: C++ requires a type specifier for all declarations
                UPROPERTY(EditAnywhere, Category=Triangle)
                                        ^
/home/raptor/Documents/Unreal Projects/MyProject/Plugins/MyPlugin/Source/MyPlugin/Private/MyPlugin.cpp:340:3: error: C++ requires a type specifier for all declarations
                UPROPERTY(EditAnywhere, Category=Triangle)
                ^
/home/raptor/Documents/Unreal Projects/MyProject/Plugins/MyPlugin/Source/MyPlugin/Private/MyPlugin.cpp:340:45: error: expected ';' at end of declaration list
                UPROPERTY(EditAnywhere, Category=Triangle)
                                                          ^
                                                          ;
/home/raptor/Documents/Unreal Projects/MyProject/Plugins/MyPlugin/Source/MyPlugin/Private/MyPlugin.cpp:342:13: error: C++ requires a type specifier for all declarations
                UPROPERTY(EditAnywhere, Category=Triangle)
                          ^
/home/raptor/Documents/Unreal Projects/MyProject/Plugins/MyPlugin/Source/MyPlugin/Private/MyPlugin.cpp:342:27: error: C++ requires a type specifier for all declarations
                UPROPERTY(EditAnywhere, Category=Triangle)
                                        ^
/home/raptor/Documents/Unreal Projects/MyProject/Plugins/MyPlugin/Source/MyPlugin/Private/MyPlugin.cpp:342:3: error: C++ requires a type specifier for all declarations
                UPROPERTY(EditAnywhere, Category=Triangle)
                ^
/home/raptor/Documents/Unreal Projects/MyProject/Plugins/MyPlugin/Source/MyPlugin/Private/MyPlugin.cpp:342:45: error: expected ';' at end of declaration list
                UPROPERTY(EditAnywhere, Category=Triangle)
                                                          ^
                                                          ;
/home/raptor/Documents/Unreal Projects/MyProject/Plugins/MyPlugin/Source/MyPlugin/Private/MyPlugin.cpp:340:36: error: use of undeclared identifier 'Triangle'
                UPROPERTY(EditAnywhere, Category=Triangle)
                                                 ^
/home/raptor/Documents/Unreal Projects/MyProject/Plugins/MyPlugin/Source/MyPlugin/Private/MyPlugin.cpp:342:36: error: use of undeclared identifier 'Triangle'
                UPROPERTY(EditAnywhere, Category=Triangle)
                                                 ^
/home/raptor/Documents/Unreal Projects/MyProject/Plugins/MyPlugin/Source/MyPlugin/Private/MyPlugin.cpp:348:40: error: expected class name
class FCustomMeshVertexBuffer:  public FVertexBuffer {
                                       ^
/home/raptor/Documents/Unreal Projects/MyProject/Plugins/MyPlugin/Source/MyPlugin/Private/MyPlugin.cpp:350:11: error: use of undeclared identifier 'FDynamicMeshVertex'
                        TArray<FDynamicMeshVertex> Vertices;
                               ^
/home/raptor/Documents/Unreal Projects/MyProject/Plugins/MyPlugin/Source/MyPlugin/Private/MyPlugin.cpp:360:39: error: expected class name
class FCustomMeshIndexBuffer:  public FIndexBuffer {
                                      ^
/home/raptor/Documents/Unreal Projects/MyProject/Plugins/MyPlugin/Source/MyPlugin/Private/MyPlugin.cpp:372:41: error: expected class name
class FCustomMeshVertexFactory:  public FLocalVertexFactory {
                                        ^
/home/raptor/Documents/Unreal Projects/MyProject/Plugins/MyPlugin/Source/MyPlugin/Private/MyPlugin.cpp:384:38: error: expected class name
class FCustomMeshSceneProxy:  public FPrimitiveSceneProxy {
                                     ^
fatal error: too many errors emitted, stopping now [-ferror-limit=]
20 errors generated.

my .cpp file

#include <IMyPlugin.h>

USTRUCT(BlueprintType)
struct FCustomMeshTriangle {
	GENERATED_USTRUCT_BODY()
		UPROPERTY(EditAnywhere, Category=Triangle)
		FVector Vertex0;
		UPROPERTY(EditAnywhere, Category=Triangle)
		FVector Vertex1;
		UPROPERTY(EditAnywhere, Category=Triangle)
		FVector Vertex2;
};
class FCustomMeshVertexBuffer:  public FVertexBuffer {
  public:
			TArray<FDynamicMeshVertex> Vertices;
		std::weak_ptr<FCustomMeshVertexBuffer> __weakref__;
	bool __initialized_FCustomMeshVertexBuffer;
	constexpr static const char* __class__ = "FCustomMeshVertexBuffer";
	virtual std::string get_class_name(){ return std::string("FCustomMeshVertexBuffer");}
	void InitRHI();
};
class FCustomMeshIndexBuffer:  public FIndexBuffer {
  public:
			TArray<int32> Indices;
		std::weak_ptr<FCustomMeshIndexBuffer> __weakref__;
	bool __initialized_FCustomMeshIndexBuffer;
	constexpr static const char* __class__ = "FCustomMeshIndexBuffer";
	virtual std::string get_class_name(){ return std::string("FCustomMeshIndexBuffer");}
	void InitRHI();
};
class FCustomMeshVertexFactory:  public FLocalVertexFactory {
  public:
			FCustomMeshVertexFactory() {}
		std::weak_ptr<FCustomMeshVertexFactory> __weakref__;
	bool __initialized_FCustomMeshVertexFactory;
	constexpr static const char* __class__ = "FCustomMeshVertexFactory";
	virtual std::string get_class_name(){ return std::string("FCustomMeshVertexFactory");}
	void Init(const FCustomMeshVertexBuffer* VertexBuffer);
};
class FCustomMeshSceneProxy:  public FPrimitiveSceneProxy {
  public:
			UMaterialInterface* Material;
			FCustomMeshVertexBuffer VertexBuffer;
			FCustomMeshIndexBuffer IndexBuffer;
			FCustomMeshVertexFactory VertexFactory;
			FMaterialRelevance MaterialRelevance;
			FCustomMeshSceneProxy(UCustomMeshComponent* Component) : FPrimitiveSceneProxy(Component), MaterialRelevance(Component->GetMaterialRelevance()) {}
		std::weak_ptr<FCustomMeshSceneProxy> __weakref__;
	bool __initialized_FCustomMeshSceneProxy;
	constexpr static const char* __class__ = "FCustomMeshSceneProxy";
	virtual std::string get_class_name(){ return std::string("FCustomMeshSceneProxy");}
	~FCustomMeshSceneProxy();
	void DrawDynamicElements(FPrimitiveDrawInterface* PDI, const FSceneView* View);
	FPrimitiveViewRelevance  GetViewRelevance(const FSceneView* View);
	uint32 GetMemoryFootprint() const;
	uint32 GetAllocatedSize() const;
};
UCLASS(hidecategories=(Object,LOD, Physics, Collision), editinlinenew, meta=(BlueprintSpawnableComponent), ClassGroup=Rendering)
class UCustomMeshComponent:  public UMeshComponent {
GENERATED_UCLASS_BODY()
  public:
			TArray<FCustomMeshTriangle> CustomMeshTris;
			UCustomMeshComponent( const FPostConstructInitializeProperties& PCIP ) : Super( PCIP )
			{
				PrimaryComponentTick.bCanEverTick = false;
				SetCollisionProfileName(UCollisionProfile::BlockAllDynamic_ProfileName);
			}
		std::weak_ptr<UCustomMeshComponent> __weakref__;
	bool __initialized_UCustomMeshComponent;
	constexpr static const char* __class__ = "UCustomMeshComponent";
	virtual std::string get_class_name(){ return std::string("UCustomMeshComponent");}
	virtual FPrimitiveSceneProxy* CreateSceneProxy() override;
	virtual int32 GetNumMaterials() const override;
	virtual FBoxSphereBounds  CalcBounds(const FTransform & LocalToWorld) const override;
};

class FMyPlugin : public IMyPlugin {
	virtual void StartupModule() override {
	std::cout << std::string("TESTING MYBLUEPRINT...") << std::endl;
}
	virtual void ShutdownModule() override {	
	std::cout << std::string("MYPLUGIN EXIT") << std::endl;
}
};
IMPLEMENT_MODULE( FMyPlugin, MyPlugin )
	void FCustomMeshVertexBuffer::InitRHI() {
		std::cout << std::string("vertex buffer InitRHI...") << std::endl;
	}
	void FCustomMeshIndexBuffer::InitRHI() {
		std::cout << std::string("index buffer InitRHI...") << std::endl;
	}
	void FCustomMeshVertexFactory::Init(const FCustomMeshVertexBuffer* VertexBuffer) {		
		std::cout << std::string("Init mesh factory...") << std::endl;
	}
	FCustomMeshSceneProxy::~FCustomMeshSceneProxy() {
		std::cout << std::string("proxy free...") << std::endl;
		VertexBuffer.ReleaseResource();
		IndexBuffer.ReleaseResource();
		VertexFactory.ReleaseResource();
	}
	void FCustomMeshSceneProxy::DrawDynamicElements(FPrimitiveDrawInterface* PDI, const FSceneView* View) {
		std::cout << std::string("proxy draw dynamic...") << std::endl;
	}
	FPrimitiveViewRelevance  FCustomMeshSceneProxy::GetViewRelevance(const FSceneView* View) {
		std::cout << std::string("proxy get view relevance") << std::endl;
	}
	uint32 FCustomMeshSceneProxy::GetMemoryFootprint() {
		return (sizeof((*this)) + this->GetAllocatedSize());
	}
	uint32 FCustomMeshSceneProxy::GetAllocatedSize() {
		return FPrimitiveSceneProxy::GetAllocatedSize();
	}
	FPrimitiveSceneProxy* UCustomMeshComponent::CreateSceneProxy() {
		FPrimitiveSceneProxy*  Proxy;
		if (( CustomMeshTris->Num() > 0 )) {
			Proxy = ( new FCustomMeshSceneProxy)->__init__(this);
		}
		return Proxy;
	}
	int32 UCustomMeshComponent::GetNumMaterials() {
		return 1;
	}
	FBoxSphereBounds  UCustomMeshComponent::CalcBounds(const FTransform & LocalToWorld) {
		FBoxSphereBounds NewBounds;
				NewBounds.Origin = FVector::ZeroVector;
				NewBounds.BoxExtent = FVector(HALF_WORLD_MAX,HALF_WORLD_MAX,HALF_WORLD_MAX);
				NewBounds.SphereRadius = FMath::Sqrt(3.0f * FMath::Square(HALF_WORLD_MAX));
				return NewBounds;
	}

Looks like you’re missing the include for your .generated.h file? Since you’re using the master branch, that should also drag in the required ObjectMacros.h for you, but in 4.15 you’d need to include that yourself.

EDIT: I misread that you were trying to do that in a .cpp file. No, that’s not possible. What we’d do internally is made a header in the Private folder of your module and include it where needed.

1 Like