Cannot find DLL when using an UObject exported via plugin from game module code

I tried this and it DOES NOT WORK. All my plugin modules are set up fine, proper _API, etc (i can link just fine from one module to the next using Public/PrivateDependencyModuleNames) but what happens is that, if i dllimport a plugin module from MyGame module, i get an windows error about Prefix-MyPluginDllName.dll being missing (also LogModuleManager:Warning: ModuleManager: Unable to load module ‘C:/Projects/Unreal/UnrealEngine/Projects/PhosphorGame/Binaries/Win64/UE4Editor-PhosphorGame.dll’ because the file couldn’t be loaded by the OS.) How do i tell it that it’s supposed to be a PLUGIN and that it should use the PLUGIN DLL SEARCH PATH to get to it ? Paper2D and Script and UdpMessaging are ALREADY LOADED at this point so it’s not too early to be loading plugins. I tried specifying AdditionalPlugins and such in the MyGame.target.cs file but it does nothing. If i add the plugin module name to OutExtraModuleNames i get this error from UBT: error : Module “CompositeModelComponent” linked into both C:ProjectsUnrealUnrealEngineProjectsPhosphorGamePluginsRuntimeCompositeModelBinariesWin64UE4Editor-CompositeModelComponent.dll and …BinariesWin64UE4Editor-CompositeModelComponent.dll, which creates ambiguous linkage for dependents.

Please note that it’s completely just a DLL search path problem, if i manually copy the plugin dll to MyGame/Binaries/Win64/ so it’s next to the game module DLL, then it loads fine.

It does not matter if my plugin resides in Engine/Plugins or MyGame/Plugins, the problem is the same

Related to https://answers.unrealengine.com/questions/13691/using-a-plugin-in-c-code.html i guess, and yes i am aware i am making a hard dependency like this, but you cannot exactly spawn new types of UObjects without depending on their StaticClass from the dll.

Editing the .uplugin file and setting the linked-in module’s Loading stage to PreDefault works around this problem. However, what if it wasn’t my plugin and I didnt want to modify it ? Surely adding [Plugins] +EnabledPlugins=PluginName to DefaultEngine.ini should make it load before the game code ? Or some other way of specifying plugin load order without modifying the plugin itself ?

You created your module as a plug-in, but you are using it as a library. This will not work, and it is also bad practice.

Library modules must reside inside your game’s Source directory. They will then either be linked directly into your game’s executable as a static library (monolithic build, i.e. game) or they will create a DLL that is loaded at run-time (non-monolithic builds, i.e. Editor). While the Engine will look for plug-in modules in the plugin directories, it will not try to look for library modules in the plug-in directories. All library modules are either statically linked into the executable, or they are located inside the Binaries directories. That is why you can make it work if you manually copy your DLL into the Binaries directory - you are basically pretending that your plug-in module is a library.

Please note that plug-ins are intended to implement some API in the Engine or your game. Plug-ins therefore have a dependency on Engine and game modules, but the reverse is not true. For a plug-in to be truly a plug-in (i.e. optional, not required), neither the Engine nor your game must know about its existence. If your game has a hard dependency on your plug-in module, then it is not really a plug-in.

You have two options:

  1. Convert your plug-in module to a true plug-in and remove the game’s dependency to this module. Your game should provide some abstract API (through interface classes) that your plug-in module can implement. UdpMessaging is an example for a plug-in module that extends an existing API (the Messaging API).

  2. Convert your plug-in module to a library module and make it not a plug-in. The module’s code should be located inside your game’s Source directory. Your game can retain the hard dependency to this module. When your module gets compiled as a DLL, it will automatically be located in your game’s Binaries directory. Note that your game can have any number of modules. Check out the ShooterGame sample game, for example.

In general, do not have modules that are both libraries and plug-ins. You are basically saying that your module is and is not a plug-in at the same time. That is bad software design, and you will become very unhappy very quickly.

So how come CustomMeshComponent, CableComponent, etc, are all plug-ins then ? I’m basically doing the same thing here, the only ‘hard’ link is the ::StaticClass call to instantiate it.

The Engine doesn’t have a module dependency to CableComponent, CustomMeshComponent etc. They are true plug-ins (i.e. option 1). The Engine doesn’t know about these modules.

Yet and you can place them in the scene, inside a blueprint, etc. I can do this with my plugin as well, UNTILL i need to make an instance of it from my game code, which is when the linker fails to find CompositeMeshComponent::StaticClass() unless i add it as a hard dependency.

See, CableComponent, CustomMeshComponent etc. are never referenced from Engine code. The Engine does not know about these types at compile time. If your game code must create instances of your custom types, then those types have to be in a regular module, not a plug-in. Plug-in means that your game code has no need to know the particular types at compile time - they are plugged in at runtime.

Does that make sense?

I don’t know why it’s ok to create instances of them in levels and BPs but not from game code. Game code and BPs should be treated similarly.

The Editor, including the Blueprint system can discover UObject based classes at runtime. If your plug-in module contains UObject classes, they will automatically register themselves with the UObject sub-system in the Engine. The Engine and the Editor can then use these types that were added at runtime.

When you wish to use UObject classes within code, then the compiler that compiles your code has to know these types at compile time. But the compiler cannot know such types at compile time in the general case, because you may not even have the code for such plug-ins.

So, the difference is that, if you wish to use your classes in code then they must be known ahead of time. If you use your types at runtime, i.e. in Blueprints, then they don’t have to be known ahead of time, but can be discovered later.

I know technically why that’s the case, just not why using it from BP keeps it a “true” plug-in, but using it from code is a bad thing and must be avoided blah blah. Maybe i want to use it in all my games, so if i make it an engine plugin that’s just an easier way of doing that vs copy pasting a game module into every game.

Because Blueprints are not code. When you create a Blueprint graph, no C++ gets compiled. Instead the graph will be compiled into byte code that will run on a virtual machine in the Engine. To create, compile and execute the Blueprint graph, no C++ types are needed.

In contrast to that, when you use your class in C++, then the C++ compiler must know the C++ type declaration.

Blueprints happen at runtime, code happens at compile time. That’s why UObjects from plug-ins can be used at runtime, but not at compile time.

Again, plug-in means that someone can extend your game’s functionality without having to recompile the game. But the usage of C++ classes requires recompiling the game. Therefore, if it requires recompiling the game, it is - by definition - not a plug-in.

Resurrecting this thread from the past since it is still not clear to me. I get why you want to not create a dependency. But in the game code I really do want to make some things core to the game and not go through BP or such hoops to work.

So, for example, if I want characters to be able to climb ropes, I want to test for interaction with the CableActor. I can make a new plugin in my game code MyCableActor/MyCableComponent or such and that works great. But now I want to see if the player is near any MyCableActor. So I do a get actors in volume or trigger or such and test if they can be cast to MyCableActor. Only I can’t link that.

Do I need to convert my Plugin to an non-plugin that still works in editor the same? If so how? I really want for best performance that the character can access members of the MyCableComponent direct. No indirection loops are wanted.

Just set your plugin’s loading stage to PreDefault and it will load before the game module, no more dll search problems :smiley: Alternatively you can just NOT use ::StaticClass, instead get the UClass via UObject FindObject