Hello, I followed the official documents scattered across the Internet and finally wrote this code. But for some reason, even I used the exactly same name with the plugin, the log wrote “Failed to retrive plugin.” here, which means gPluginSuite→GetNamedPlugin() didn’t work out and no plugin reference has been retrieved so that I couldn’t use it on sUxpProcs→SendUXPMessage(gPlugInRef, UXP_MANIFEST_ID, desc); Can anyone help me?
c.f. From the log file, I confirmed this function has been automatically called when I open up my plugin. (Because this is not the automation plugin nor the filter plugin so I couldn’t use any examples on the example code on the website.)
#include <exception>
#include <stdexcept>
#include <string>
#include <fstream>
#include "utilities/UxpAddon.h"
#include "utilities/UxpTask.h"
#include "utilities/UxpValue.h"
#include "SPBasic.h"
#include "SPPlugs.h" // Required for SPPlugins suite
#include "SPProps.h" // Required for accessing plugin properties
#include "PIUXPSuite.h" // For messaging
#include "PIActions.h" // For PIActionDescriptor
#include "PIGeneral.h" // For PlugInInfor Struct
#include "PIColorSpaceSuite.h"
// For general use of CSDK API. (without any interaction or messages)
static const SPBasicSuite* gBasicSuite = nullptr;
static const PSColorSpaceSuite2* gColorSpaceSuite = nullptr;
// My globals
SPPluginRef gPlugInRef = nullptr; // This is passed to your main function
static const SPPluginsSuite* gPluginSuite = nullptr;
PsUXPSuite1* sUxpProcs = nullptr; // * Acquired this inside of the function.
PSActionDescriptorProcs* sDescriptorProcs = nullptr; // * Acquired this inside of the function.
// To receive a message from a UXP plugin
void UXPMessageHandler(PIActionDescriptor descriptor) {
// do something
}
void writeLog(const std::string& message) {
std::ofstream logFile;
logFile.open("/Users/astrydpark/pluginLog.txt", std::ios_base::app); // Open in append mode.
// (Added) If std::ios_base::app is not inserted, the logging system wouldn't work properly.
if (logFile.is_open()) {
logFile << message << std::endl; // Write message to file
logFile.close(); // Close the file after writing
} else {
printf("Unable to open log file.\n");
}
}
extern "C" UXP_EXTERN_API_STDCALL(SPErr) PSDLLMain(const char* selector, SPBasicSuite* spBasic, void*) {
// In automation plugin, void* could be handled as a 'message' but here it doesn't.
try {
do {
writeLog("Hello world."); // Confirmed. This function is naturally called when the plugin is launched.
// Cache the basic suite so we can use at any time
gBasicSuite = spBasic;
// writeLog("Start acquiring kPSUXPSuite.");
SPErr uxp = gBasicSuite->AcquireSuite(kPSUXPSuite, kPSUXPSuiteVersion1, (const void**)&sUxpProcs);
SPErr action = gBasicSuite->AcquireSuite(kPSActionDescriptorSuite, kPSActionListSuiteVersion, (const void**)&sDescriptorProcs);
if (uxp != kSPNoError || action != kSPNoError) {
writeLog("Cannot acquire kPSUXPSuite.");
writeLog("Cannot acquire kPSActionDescriptorSuite.");
break;
}
// writeLog("Done acquiring kPSUXPSuite and kPSActionDescriptorSuite.");
SPErr spErr = gBasicSuite->AcquireSuite(kPSColorSpaceSuite, kPSColorSpaceSuiteVersion, reinterpret_cast<const void**>(&gColorSpaceSuite));
if (spErr != kSPNoError) {
writeLog("Cannot acquire kPSColorSpaceSuite.");
break;
}
if (gColorSpaceSuite == nullptr) {
writeLog("gColorSpaceSuite is NULL.");
break;
}
Color8 colorArray[1] = {11, 30, 201, 0}; // Blue RGB Colour
spErr = gColorSpaceSuite->Convert8(plugIncolorServicesRGBSpace, plugIncolorServicesCMYKSpace, colorArray, 1);
if (spErr != kSPNoError) {
writeLog("Failed to convert colour space.");
break;
}
// c.f. There's a thing called PIGeneral.h - PlugInInfo, but it's totally useless in this situation.
SPErr plugin = gBasicSuite->AcquireSuite(kSPPluginsSuite, kSPPluginsSuiteVersion, (const void**)(&gPluginSuite));
if (plugin != kSPNoError) {
writeLog("Failed to acquire kSPPluginsSuite.");
break;
}
// Retrieves a plugin reference by its name.
SPErr test = gPluginSuite->GetNamedPlugin("My Plugin", &gPlugInRef);
if (test != kSPNoError) {
writeLog("Failed to acquire plugin reference.");
break;
}
// I think it's making a message here?
PIActionDescriptor desc; // So, 'desc' is just a frame that build messages?
sDescriptorProcs->Make(&desc);
sDescriptorProcs->PutString(desc, 'helo', "Hello World!");
sDescriptorProcs->PutFloat(desc, 'fltp', 0.952);
// writeLog("Done creating a message.");
// Our plugin id
const char* UXP_MANIFEST_ID = "my-plugin-id";
// writeLog("Built the message.");
// FINAL Step: Send out a message to specified plugin!
/*
if (gPlugInRef) {
writeLog("gPlugInRef address: " + std::to_string(reinterpret_cast<uintptr_t>(gPlugInRef)));
}
*/
sUxpProcs->SendUXPMessage(gPlugInRef, UXP_MANIFEST_ID, desc);
writeLog("***Successfully changed the colour mode and sent out the message.***");
} while (false);
return kSPNoError;
}
catch(...) {
writeLog("An exception occurred in PSDLLMain.");
return -1;
}
}
// Underneath here is typical namespace Photoshop DOM API code, so I excluded those from this.