GeLoadString() always StrNotFound

On 08/05/2017 at 12:12, xxxxxxxx wrote:

Hi again! 😉

Next question: i have a "external" stringtable (as .str in res/strings_us/description/) and want to get an item in actual language.

print plugins.GeLoadString(c4d.ID_TEST)   

always returns "StrNotFound"...
What's i'm doing wrong?

Grateful for any help,

On 10/05/2017 at 09:52, xxxxxxxx wrote:


Sorry, but i don't unterstand, how to work with the GeResources... so i have to ask you again:
After registering my TagPlugin i want to get a sentence from the Stringtable by it's ID. How is this possible? Is it possible?

I've tried to load the resource files with GeResource.Init(path), but the function replies it requires a 'c4d.plugin.GeResource'?

Thanks for any advice,

On 10/05/2017 at 19:53, xxxxxxxx wrote:


The LoadString() function seems to only deal with the .str file found in the "strings_us" folder.
I don't think you can use it to get the items from the .str file in the "description" folder.
But I could be wrong. You'll have to get confirmation from the support guys about it next week.

To make things even more convoluted. It seems that you also need to use the c4d_symbols.h file to declare the item ID#s. Which most people do not use for Python plugins. Because it's not supported.
So if you're using an .h file in your description folder. Those ID's will need to be copied into the c4d_symbols.h file.
This makes the LoadString() function possibly not a great thing to use in Python.
In C++ we use the c4d_symbols.h file a lot. So it's usage is far less clumsy.

Here are my notes about using the LoadString() function in Python:

#LoadString() loads the resource items in the .str file in node based plugins  
#IMPORTANT! There are two folders where an .str file exists: "strings_us" & "description"  
#The LoadString() function only loads the items from the .str file found in the "strings_us" folder(or strings_de, etc...)  
#These .str items must also be given their ID#s from the c4d_symbols.h file  
#Since Python does not use the c4d_symbols.h file. It's usually empty...Don't get tripped up on this!!!!  
#Most Python plugins declare the gizmo ID#s in an .h file located in the "description" folder  
#Therefore, LoadString() will throw StrNotFound errors unless you also add them to the c4d_symbols.h file  
#This code loads all of the .str resource items for all of the registered plugins in C4D(lots of them)  
      resource = c4d.plugins.GeResource()  
      for i in xrange(0,400000) :  
          s = resource.LoadString(i)  
          if s != "StrNotFound": print s  
#This code loads the .str items that are in the "strings_us" folder  
#Reminder. If the ID#s are not being generated in the c4d_symbols.h file you'll get StrNotFound errors  
      dir, file = os.path.split(__file__)   #Gets the plugin's directory   
      resource = c4d.plugins.GeResource()        
      for i in xrange(0,20) :  
          s = resource.LoadString(i)  
          if s != "StrNotFound": print s, "  ", i

If you want to get the strings directly from the .str file that's in your "description" folder. The LoadString() function might not be a good option. But I'm no expert on this.
It might be better to use descriptions to get at them.
The support guys will probably offer better ideas when they get back next week.


On 16/05/2017 at 03:03, xxxxxxxx wrote:

Hi Mark,

plugins.GeLoadString() only works with strings defined in a plugin global resource file c4d_strings.str
For strings defined inside res/strings_xx/description plugins.GeLoadString() returns "StrNotFound".

If you need a specific string, define its ID inside res/c4d_symbols.h and add it to the global resource file res/string_xx/c4d_strings.str
res/c4d_symbols.h is useless for Python plugins because definitions from this file are not added to the c4d module.
There are several solutions to get the ID into the plugin's code:
- Manually define the ID name and value inside your plugin pyp file (fastest solution)
- Add a file to the res folder with this content:

IDS_MYGLOBALSTRING = 10000 # Defined as IDS_MYGLOBALSTRING inside  _res/c4d_symbols.h_
... # define more strings ID

And then import res into the pyp file making sure to add the plugin folder to the Python search path:

folder = os.path.dirname(__file__)
if folder not in sys.path:
    sys.path.insert(0, folder)

You can now use the defined string ID with res.IDS_MYGLOBALSTRING
This solution is better because pythonic.

GeResource.Init() has to be called on a valid GeResource object, it's not a static method.
From within a pyp Cinema 4D python plugin file __res__ global variable refers to the GeResource object for the plugin. This means it's better to use __res__ instead of creating a new GeResource.

On 16/05/2017 at 11:49, xxxxxxxx wrote:

Hi ScottA,
Hi Yannick,

thank you very very much for your answers and help!
On my actual plugin i decided to make a compromise without "GeLoadString", but now i knew it better for the future... 🙂

Thanks and Cheers,