Skip to main content
Participant
February 19, 2025
Question

Best practice for intercommunication between C++ plugins and CEP extensions?

  • February 19, 2025
  • 2 replies
  • 802 views

Hello.

 

After much searching around the web, C++ SDK files, and documentation, I can only conclude that there doesn't seem to be any officially endorsed methods by Adobe for supporting listener/event-based communication between C++ plugins and CEP extensions (or even between C++ and ExtendScript for that matter).

 

For CEP <-> ExtendScript, this is a solved problem using CSXS Events / PlugPlug. 

 

However, for:

 

  • C++ <-> CEP 
  • C++ <-> ExtendScript

 

There is no native listener/event intercommunication system; at least, nothing in the SDK or any developer forums online seems to suggest so. From what I can gather, there appear to be at least four possible, but not ideal, options on the table:

 

  • Grafting the Adobe Illustrator SDK code for the PlugPlug library into After Effects (Ref 1, Ref 2). This seems inconclusive / vaguely plausible at best, and a wild goose chase at worst. This seems like it could work on paper, but it reads like a hacky solution to try and amalgamate code from another SDK. No one has concluded (at least in public forums) that this is viable. 

 

  • Using files - it is straightforward to have a CEP Extension / ExtendScript write to a file which we then instruct the C++ to look at (Ref 1). This is verified to be possible, but seems horrendously inefficient, given that we would need to introduce I/O operations and latency for something as fundamental as inter-code communication.

 

  • Websockets - As CEP Extensions use Node.js, which is literally a server, we could, in theory, communicate bidirectionally by having a server running in the C++ plugin. This seems like a solid way to support listening/events between the two, but I would be concerned about the potential computational cost/implementation, given I have limited knowledge in this area. This is likely my first option to research without an official option.

 

  • Using AEGP_ExecuteScript() - C++ can execute ExtendScript (as can CEP Extensions), so you could implement a sort-of polling method to pass information between the two using global objects, but this would incur a lot of computational cost having the C++ plugin use AEGP_ExecuteScript() repeatedly to check for changes or new information. You could set up some conditional rules, but again, this is not elegant.

 

Before I go ahead and try one of these methods out, I thought it was worth adding my own question to this pile of unresolved forum threads in hopes that someone figured out a standardised way to do this basic operation after a decade of CEP extensions being available.

 

Cheers!

2 replies

Community Expert
February 19, 2025

I don't know of any "standardized" method for such intercom, but of all the ways you have suggested, i would go with AEGP_ExecuteScript() polling.

before going into WHY i'd suggest that way, i'll say that CEP is being deprecated for UXP. the main difference being that UXP communicate with AE synchronously.

back to the "why". ae doesn't like to be talked to at just any time. ae wan't to be talked to only during certain times and only on the main thread. as Alex White said, you could write an ExternalObject plugin and find a way to trigger it directly. alas, that component woulnd need to talk to AE only during certain time slots which AE triggers, such as the idle process callback. that already becomes a polling mechanism, but it involves an extra component instead of just using extendscript as the intermediate.

E1025Author
Participant
February 19, 2025

Thank you for your prompt reply.

 

C++ <-> ExtendScript communication is possible, but compiling the ExternalLibrary would require some struggle and IMHO it is not worth it nowadays. ExtendScript should only do ExtendScript things and avoid communication with file system.

 

This is fine, as I can facilitate this through my CEP extension if necessary or have the CEP execute ExtendScript itself.

 

C++ <-> CEP. Choosing the right way of passing the data and intercommunication protocol highly depends on what exact feature you are trying to implement and what kind of data to pass. So far, the easiest and most reliable way is to use Websockets and that's what I'm doing inside my tools as well.

 

All I would be looking to do is the following:
 
Facilitate giving both my CEP extension and my C++ plugin the ability to send and receive serialised JSON objects between each other (and acknowledge a response) in a computationally cheap manner.
 
I am assuming that if I added a Websocket client to the C++ extension, there would be no sandboxing/visibility issues, and connecting it to the node.js server in the CEP extension is a straight shot. 
 
I'll take a look into simple Websocket client options. Are there any potential hurdles I should be aware of?

quote

as Alex White said, you could write an ExternalObject plugin and find a way to trigger it directly. alas, that component woulnd need to talk to AE only during certain time slots which AE triggers, such as the idle process callback. that already becomes a polling mechanism, but it involves an extra component instead of just using extendscript as the intermediate.

 

I did omit in my original post that I found an example of a hybrid C++/ExtendScript plugin, which:

  • Used a .jsx ScriptUI panel with buttons configured to trigger functions in its C++ component using ExternalObject
  • Recieved values from those functions triggered directly back into the ExtendScript

Ideally I would like to do something similar to this as you could also impliment the same form of communication to the C++ plugin from a CEP Extension. Because I couldn't find any documentation in the SDK related to ExternalObject (please let me know if there might be) or examples of what the C++ side might look like, I assumed this was being done by painfully constructing something bespoke similar to the first potential solution using parts of the Illustrator SDK. So clearly there is a precident for a cleaner solution than polling with ExecuteScript,  but in the absense of detailed examples/documentation on how to use ExternalObject / ExternalLibrary in the manner above I feel the ExecuteScript option feels like a stopgap (although I do appreciate the point that you are making).

 

Thanks again.

 

Community Expert
February 19, 2025

there are no AE specific doct for ExternalObject. all the external object docs and sdk samples are installed along with the old extendscript tools at "C:\Program Files (x86)\Adobe\Adobe Utilities - CS6\ExtendScript Toolkit CS6\SDK".
are there any other docs lurking in the deep dark web? i haven't a clue...

Alex White
Legend
February 19, 2025

C++ <-> ExtendScript communication is possible, but compiling the ExternalLibrary would require some struggle and IMHO it is not worth it nowadays. ExtendScript should only do ExtendScript things and avoid communication with file system.

 

C++ <-> CEP. Choosing the right way of passing the data and intercommunication protocol highly depends on what exact feature you are trying to implement and what kind of data to pass. So far, the easiest and most reliable way is to use Websockets and that's what I'm doing inside my tools as well.