• Global community
    • Language:
      • Deutsch
      • English
      • EspaƱol
      • FranƧais
      • PortuguĆŖs
  • ę—„ęœ¬čŖžć‚³ćƒŸćƒ„ćƒ‹ćƒ†ć‚£
    Dedicated community for Japanese speakers
  • ķ•œźµ­ ģ»¤ė®¤ė‹ˆķ‹°
    Dedicated community for Korean speakers
Exit
3

Maintaining compatibility with multiple versions of InDesign SDK

Explorer ,
Jan 30, 2024 Jan 30, 2024

Copy link to clipboard

Copied

I can see that in SDK version 14.0.1, there is no bool searchBackwards=false parameter in FindError abstract function in ISpellingService:

virtual SpellResult FindError( const WideString &rParagraph, int32 startAt, int32 *pErrorStart, int32 *pErrorLength, WideStringList* pAlternatives) = 0;

Whereas in later versions it has:

virtual SpellResult FindError( const WideString &rParagraph, int32 startAt, int32 *pErrorStart, int32 *pErrorLength, WideStringList* pAlternatives, bool searchBackwards=false) = 0;

The plugin source code is located in generic location, and compiling without any issues with multiple SDK versions above 14.

But failing for version 14, with error:

'THCSpelling': cannot instantiate abstract class
1>  D:\<path>\THCSpelling.cpp(83,7): message : see declaration of 'THCSpelling'
1>  D:\<path>\THCSpelling.cpp(219,1): message : due to following members:
1>  D:\<path>\THCSpelling.cpp(219,1): message : 'ISpellingService::SpellResult ISpellingService::FindError(const WideString &,int32,int32 *,int32 *,WideStringList *)': is abstract

To avoid this issue, I'm trying to update my plugin source code to maintain compatibility with older versions of SDK such as 14. I'm trying conditional definition of a FindError function using macros:

#include <SDKDef.h>

...

class THCSpelling : public CPMUnknown<ISpellingService> {

...

#if kSDKDefPlugInMajorVersionNumberForResource > 14
    virtual ISpellingService::SpellResult FindError(const WideString& rParagraph, int32 startAt, int32* pErrorStart, int32* pErrorLength, WideStringList* pAlternatives, bool dir = kFalse);
#else
    virtual ISpellingService::SpellResult FindError(const WideString& rParagraph, int32 startAt, int32* pErrorStart, int32* pErrorLength, WideStringList* pAlternatives);
#endif

...

}

But this isn't working as expected.  Even though `kSDKDefPlugInMajorVersionNumberForResource`  is equal to 19, the part after the #else getting executed during compile time which is resulting in error.

 

I'm sure that this is related with "chained" defines

In SDKDef.h:

#define kSDKDefPlugInMajorVersionNumberForResource    kMajorVersionNumberForResource

In BuildNumber.h:

#define kMajorVersionNumberForResource    kCC19MajorVersionNumberForResource

In CC19BuildNumber.h:

#define kCC19MajorVersionNumberForResource    19

 

Because defining a custom macro directly in the working file working correctly. But, interestingly, directly comparing the kCC19MajorVersionNumberForResource (which is clearly defined as 19) for being greater than 14 is not working. I'm confused...

 

I will be waiting for your help in resolving the issue, thanks!

TOPICS
SDK

Views

188

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines

correct answers 1 Correct answer

Guide , Jan 31, 2024 Jan 31, 2024

No preprocessor tricks required.

 

In C++ you can have multiple functions with the same name in the same scope, as long they differ by their argument list. This mechanism is called "overloaded member function". So you can provide the old interface's function and forward the call to the new interface's function, adding the extra argument.

 

In the case of the newer interface your old style method would get stripped away by the linker, as long your implementation class does not declare it with the "vi

...

Votes

Translate

Translate
Contributor ,
Jan 30, 2024 Jan 30, 2024

Copy link to clipboard

Copied

Hi @jasuryusupov ,

 

Try using "kSDKDefPlugInMajorVersionNumber".

 

I can't comment why it is not working.  May be try creating the preprocessor file and check with what value it is getting replaced. You can google how to see preprocess file where all macros are replaced with actual value.

 

May be your project setup is not correct and it may be referring to different SDK folder. Try renaming your SDK folder to validate whether you are getting any compiling errors or not. If you rename your SDK folder then you should see some compiling errors.

 

I generally, create a preprocessor directive added in the project on windows and mac and use that for such scenarios.

 

- Regards,

Rahul Rastogi

Adobe InDesign SDK Custom Plugin Architect

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Jan 30, 2024 Jan 30, 2024

Copy link to clipboard

Copied

If I were you I would first identify if I am using the correct SDK so that the possibility of using a wrong defintion of macro is ruled out.

-Manan 

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Guide ,
Jan 31, 2024 Jan 31, 2024

Copy link to clipboard

Copied

LATEST

No preprocessor tricks required.

 

In C++ you can have multiple functions with the same name in the same scope, as long they differ by their argument list. This mechanism is called "overloaded member function". So you can provide the old interface's function and forward the call to the new interface's function, adding the extra argument.

 

In the case of the newer interface your old style method would get stripped away by the linker, as long your implementation class does not declare it with the "virtual" keyword.

 

My take on preprocessor tricks: note that BuildNumber.h includes all the version specific files up to the including version. So you can use #ifdef on a version specific macro to test for that version or later, or something like #if

defined(__CC14BuildNumber_h__) .

 

For more complicated cases that require different code, where method overloading does not work, try to express the condition in a more descriptive macro name, so that you can later on search for the macro name and see all related code sections, plus the underlying condition (at the macro definition).

 

E.g. to check for support of the controlstrip ui, test for InDesign version 3 or later:

 

#if defined(__DragonTailBuildNumber_h__)

#define HAS_CONTROLSTRIP 1

#else

ā€¦

 

Better also check that the macro works in both C++ compiler and the very old style preprocessor used within ODFRC.

 

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines