Linking new version of OpenSSL for packaged project

Hello,

I have an external library that requires openssl version 1.1.0.
I am adding the library to the Project.Build.cs along with openssl lib/dll files:

// openssl
PublicIncludePaths.Add(Path.Combine(ThirdPartyPath, "openssl", "include"));
PublicAdditionalLibraries.Add(Path.Combine(ThirdPartyPath, "openssl", "lib", "libsslMD.lib"));
RuntimeDependencies.Add(new RuntimeDependency(Path.Combine(binariesDir, "libsslMD.dll")));

// third party lib
PublicIncludePaths.Add(Path.Combine(ThirdPartyPath, "mylib", "include"));
PublicAdditionalLibraries.Add(Path.Combine(ThirdPartyPath, "mylib", "lib", "mylib.lib"));

When I run the project in editor everything works fine, but when I try to package and run it I get some errors. While looking at log files I noticed that I am getting this error:

Error: Unhandled Exception: EXCEPTION_ACCESS_VIOLATION 0x5f3fccd0
Error: libsslMD.dll!0x000000005F3FCCD0

But I also spotted that UE is adding the link to the OpenSSL (older version) itself:

LogInit: Using libcurl 7.47.1
LogInit:  - built for x86_64-pc-win32
LogInit:  - supports SSL with OpenSSL/1.0.2g

What is the correct way to link my third party library with the new version of OpenSLL in packaged mode? Note - I am not directly including openssl headers in unreal files.

Any help is greatly appreciated.

To get external libraries compiled into UE4 you need to put them inside a third-party plugin. You can’t just include them in your project. Good news is, once this is done you’ll be able to plug it into anything – and maybe make it available for others in a compact/clean way.

Bad news: the plugin system isn’t well-documented. Good news: I have a plugin that contains the ZeroMQ library so it could be used as an example project. Actually, this is pretty cool because I put that up on Github and no one has ever used it!! :slight_smile:

It’s here: GitHub - Jin-Vyral/ZMQUE: ZMQ for Unreal Engine 4 -- Quick & Dirty

Let me know if you have any questions or problems. The main thing I had to do was convert the API calls because the ZMQ DLL and UE4 had different ideas about what “short” meant. Hopefully, you won’t have that problem.

One other thing: I’ve never figured out how to get UE4 to package the ZMQ DLL in the game binaries directory (where it belongs). I could only get it to copy the DLL into the same path it’s in for my project. I have a batch file that always copies the DLL in before it runs my game, but there’s probably a way to point the game to the actual DLL location rather than the Binaries. Or get the game to copy the DLL itself. If you figure out how to do either of these, let me know, K?

Thanks for the response, but the main problem is that I am not using the library directly, the external library is using it, so I can’t use your solution - you’re rewriting access to the library itself. This means I would have to not only make proxy functions for every OpenSSL function, but also change the external library that is using the OpenSSL functions to use those proxies instead.

Not sure if this is what you need, but the RuntimeDependencies.Add() function seems to copy the .dll files to binary folder and add the requirement to .exe file. I used a nice app called DependencyWalker to check this and it looks good. I also tried profiling my UE project and the DLL seems to be loaded correctly:

Loaded “c:\ue…\win64\LIBSSLMD.DLL” at address 0x00007FF967FF0000. Successfully hooked module.

Loaded “c:\ue…\win64\LIBCRYPTOMD.DLL” at address 0x00007FF95ED80000. Successfully hooked module.

// after some time

DllMain(0x00007FF95ED80000, DLL_PROCESS_ATTACH, 0x000000669CE1F580) in “c:\ue…\win64\LIBCRYPTOMD.DLL” called.

DllMain(0x00007FF95ED80000, DLL_PROCESS_ATTACH, 0x000000669CE1F580) in “c:\ue…\win64\LIBCRYPTOMD.DLL” returned 1 (0x1).

Update:
While linking OpenSSL 1.0.2 in a test project using the same method everything seems to work correctly, while 1.1.0 fails, so this really looks like depency clash issue.

That’s the function that adds it to the directory it’s in for your project, not the binaries dir.

So you have two external libraries? Then they both should be in the same plugin. That’s how my plugin is set up. I have my library that UE4 uses and the ZMQ third-party DLL that my library uses. And you only need to do pass-thru functions if there is a need to convert things for UE4 like I had to. If the SSL API isn’t called in UE4 then there’s no need for any changes.

Hey,
Thanks for the suggestions but as I feared separating it into a plugin does not help. The main problem is the clash of OpenSSL versions, not the improper DLL linkage.
Even after I separated the code into a freshly made plugin I would still have problems coming from the fact that:

  • my plugin uses OpenSSL v 1.1.0

  • UE4 uses OpenSSL v 1.0.2 as part of the core engine

I am currently trying to make some kind of compatibility layer between those OpenSSL versions.

sg_badyl Hey! Did you find out any solution?

Hey, sorry for my late response.

The way I finally solved the problem is probably not the best or nicest way out there - I basically provided a ‘compatiblity’ layer for OpenSSL 1.0.2 that enhances it with the functions from 1.1.0 that I need, e.g.:

#if OPENSSL_VERSION_NUMBER < 0x10100000L

#include <string.h>
#include <openssl/engine.h>

static void *OPENSSL_zalloc(size_t num)
{
// other functions etc. go here

#endif /* OPENSSL_VERSION_NUMBER */

Then I included this in my plugin and added the normal OpenSSL dependency in Build.cs file.