Skip to main content
Brainiac
December 3, 2015
Answered

Possible to call / load an external DLL in GlobalSetup()?

  • December 3, 2015
  • 2 replies
  • 2379 views

Hi Again

So, I'm needing to use a DLL provided to me by a third party.  I need to call a function from it in GlobalSetup().  I've linked the DLL (x64) correctly as Visual Studio is building the .aex just fine.  However, when I go to debug and apply the effect to a solid, for exampe, AE tells me:

After Effects error: plugin "testplug.aex" could not be loaded (126).

(48 :: 46)

Then, I click 'OK', and when I apply the effect again it gives me the following error:

After Effects error: invalid filter

(25 :: 3)

From my experience this usually means that After Effects cannot find some kind of DLL, but I might be wrong.   When this error comes up, I do see the following in Visual Studio's debug output:

First-chance exception at 0x00007FF8BB0D871C in AfterFX.exe: Microsoft C++ exception: long at memory location 0x000000000083AE78.

First-chance exception at 0x00007FF8BB0D871C in AfterFX.exe: Microsoft C++ exception: long at memory location 0x000000000083AFAC.

First-chance exception at 0x00007FF8BB0D871C in AfterFX.exe: Microsoft C++ exception: long at memory location 0x000000000083B610.

I doubt that means anything, but just thought I would share that info in case it does.

I've pinned down the problem to the first line of code that calls a function from the third-party DLL.  When I comment out that line, everything is okay, but when I uncomment it, I get the errors above.  So, my question is if there is anything I can further to do debug the DLL issue.  The DLL was just shipped with an SDK, so I don't have access to the source.

If there is any insight you all can offer, I would be most appreciative.

Thanks and best,
Arie

This topic has been closed for replies.
Correct answer

Hey Toby,

No information overload here--I appreciate as much info on this as possible!  The only information overload is when I hit up MSDN's website and read Microsoft's documentation   Your explanation is far more appreciated.

So, I realized that I'm building against CS5's SDK since I need to support that version.  I pasted in the code you offered into my source and VS2012 is telling me that PF_PlatData_EXE_FILE_PATH_W is undefined.  I took a look at CS6 SDK PDF documentation, and it does look like it's in CS6 where they introduced PF_PlatData_EXE_FILE_PATH_W.  So, I think I'll just have to do the deprecated way you mentioned and run the risk of unicode characters in paths breaking the loading of the plugin.

I think placing the secondary .dll next to my .aex which lives in a subfolder of the /Effects directory is the way I'll try for now.  If I cannot get it to load via implementation of code, I'll just dump the .dll into the /Support Files directory even though I know it's not best practice.  Oh the dilemmas we developer's face

One question I have is once I get the path from PF_GET_PLATFORM_DATA(), how do I concatenate the name of the .dll file to the character array?

Thanks again for your time and help!  I'll post an update if I can get it to work this way.

Thanks,
Arie


Any reason you are using the CS5 SDK? CS6 is a pretty good choice these days as most of the non-subscription/cloud users are using CS6, afaik. And a basic CS6 plugin will in most cases also work in AE CC.

Here is complete code to getting the plugin folder as a std::string:

#include <string>

using namespace std;

...

A_char pluginFolderPath[AEFX_MAX_PATH];

PF_GET_PLATFORM_DATA(PF_PlatData_EXE_FILE_PATH_DEPRECATED, &pluginFolderPath);

string pluginPath = string(pluginFolderPath); // contains now the full path including plugin name

int pos = (int)pluginPath.find_last_of("\\/"); // find last folder delimiter

if (pos >= 0) pluginPath = pluginPath.substr(0, pos + 1); // grab anything before that

...

string myPluginPath = pluginPath + "My3rdPartyDll.dll";

HINSTANCE myDllHandle = LoadLibrary(myPluginPath.c_str());

2 replies

December 3, 2015

For reference, here is how getting the path to the plugin DLL can be achieved using the AE SDK:

A_UTF16Char wPath[AEFX_MAX_PATH];

PF_GET_PLATFORM_DATA (PF_PlatData_EXE_FILE_PATH_W, wPath);

You'll have to do some UTF16 juggling to get that path string into something LoadLibrary understands though, even when you use the LoadlibraryW variant.

Brainiac
December 3, 2015

Toby,

Thanks for the code, I appreciate it.  I agree that it's bad practice to pollute AE's standard /Support File directory with a third-party dll. 

What is LoadLibrary and LoadLibraryW?  Is that some kind of standard function that is included with C++?

Also, I have some questions about the code you presented.  It look like you first declared a variable named `wPath` that is an array set to a length defined by AEFX_MAX_PATH.  Then PF_GET_PLATFORM_DATA() loads PF_PlatData_EXE_FILE_PATH into the wPath array.  Is my understanding correct?  I guess I don't understand how getting the PF_PlatData_EXE_FILE_PATH will help me in loading a DLL that exists outside of AE's application folder.

For example, I would prefer to store the third-party DLL somewhere like C:\ProgramData\AppFolder\third-party.dll.  How do I implement this in my code since, from what I understan, PF_PlatData_EXE_FILE_PATH would just give me the full path to the AfterFX.exe executable.  I'm probably misunderstanding something.

Thanks again for your time and help!

—Arie

Correct answer
December 3, 2015

Hey Toby,

No information overload here--I appreciate as much info on this as possible!  The only information overload is when I hit up MSDN's website and read Microsoft's documentation   Your explanation is far more appreciated.

So, I realized that I'm building against CS5's SDK since I need to support that version.  I pasted in the code you offered into my source and VS2012 is telling me that PF_PlatData_EXE_FILE_PATH_W is undefined.  I took a look at CS6 SDK PDF documentation, and it does look like it's in CS6 where they introduced PF_PlatData_EXE_FILE_PATH_W.  So, I think I'll just have to do the deprecated way you mentioned and run the risk of unicode characters in paths breaking the loading of the plugin.

I think placing the secondary .dll next to my .aex which lives in a subfolder of the /Effects directory is the way I'll try for now.  If I cannot get it to load via implementation of code, I'll just dump the .dll into the /Support Files directory even though I know it's not best practice.  Oh the dilemmas we developer's face

One question I have is once I get the path from PF_GET_PLATFORM_DATA(), how do I concatenate the name of the .dll file to the character array?

Thanks again for your time and help!  I'll post an update if I can get it to work this way.

Thanks,
Arie


Any reason you are using the CS5 SDK? CS6 is a pretty good choice these days as most of the non-subscription/cloud users are using CS6, afaik. And a basic CS6 plugin will in most cases also work in AE CC.

Here is complete code to getting the plugin folder as a std::string:

#include <string>

using namespace std;

...

A_char pluginFolderPath[AEFX_MAX_PATH];

PF_GET_PLATFORM_DATA(PF_PlatData_EXE_FILE_PATH_DEPRECATED, &pluginFolderPath);

string pluginPath = string(pluginFolderPath); // contains now the full path including plugin name

int pos = (int)pluginPath.find_last_of("\\/"); // find last folder delimiter

if (pos >= 0) pluginPath = pluginPath.substr(0, pos + 1); // grab anything before that

...

string myPluginPath = pluginPath + "My3rdPartyDll.dll";

HINSTANCE myDllHandle = LoadLibrary(myPluginPath.c_str());

Brainiac
December 3, 2015

OMG, after debugging this for the past 24 hours, and finally posting my question here on the forum, I think I have found the answer!  If I place the third party DLL inside at this path on my system with AE installed:

C:\Program Files\Adobe\Adobe After Effects CC 2014\Support Files

Then my plugin works fine!  If I place the plugin within the Plug-ins directory or even within the Plug-ins/Effects directory, then my plugin won't load into AE. 

So, I guess my question is two-fold:  is it okay to have an installer dump a dll that my plugin needs into the '/Support Files' directory?  If not, what is the proper way of going about doing this?

Thanks,
Arie

December 3, 2015

Hi Arie,

glad you found the answer yourself.

Yes, this is how Windows works! If you load a DLL from another DLL, the second DLL will be looked for in the location of the application that loaded the first DLL, NOT in the location of the first DLL itself. If it can't find the DLL there, it will look in the system path through all directories listed there. So you can either put it in "Support Files" (where the AE .exe is), which is bad practice in my opinion, or in a custom folder that you add to the path environment variable yourself (also not so nice, but done by bigger software suites), or in a subfolder of the user's OS-specific common/application/preferences/whatever folder (some plugins do that, but you have to do it in the installer and then determine that path from your plugin as well), or you put your second DLL next to your plugin DLL, then determine in your C++ code the path where your main plugin DLL resides and is loaded from (either using OS specific functions or using a built-in AE API function) and then load your second DLL using this absolute path (recommended solution).