Reading script file into memory
-
In order to run a python script from c++, the script must be read into memory before it can be executed.
Except char and string handling in the c++ sdk is somewhat puzzling me.I have following code, but nothing happens (it seems cinema 4d is in a loop)?
Filename fname = "C:\\Program Files\\Maxon\\CINEMA 4D R20.026\\plugins\\commandline\\test.py"; AutoAlloc<BaseFile> file; // Allocate a Python script node BaseList2D* op = (BaseList2D*)AllocListNode(ID_PYTHONSCRIPT); if (op != nullptr && file->Open(fname)) { BaseContainer* data = op->GetDataInstance(); if (data == nullptr) { return false; } // Allocate a memory buffer to hold the Python script file Int64 length = file->GetLength(); // pChar* text = NewMem(Char, length + 1); // Old R15 code maxon::String text; // Read the Python script Char ch; while (file->ReadChar(&ch)) text[file->GetPosition() - 1] = ch; text[length] = '\0'; // Set the Python script text in the Python script node container data->SetString(PYTHONSCRIPT_TEXT, text); // Do not forget to delete the memory buffer for the script text // pDeleteMem(text); // Execute the script op->Message(MSG_SCRIPT_EXECUTE, nullptr);
Or should I use HF file and if so,how should I do that?
-
Easier than expected.
maxon::String text{ "" }; // Read the Python script Char ch; while (file->ReadChar(&ch)) text.AppendChar(ch);
-
Hi @pim while you already found a working solution, note that there is this manual that demonstrates how to reads a file Url Manual - Streams.
Note that it's also possible to execute Python directly see Python Manual, of course, this does not expose the script to the user, as you do in your snippet.
Cheers,
Maxime. -
Hi Maxime,
Thanks the answer, great!
Does this also means we can use a protected (pypv / pype) source? -
No that is not possible only Cinema 4D know-how to decipher pypv/e source and there is no way even from C++ API to decipher this.
But you could encrypt the file as you want and then with the code from the Python manual load the string, decipher it and execute it.
But keep in mind python is python, at a given time you will need to provide python with actual python code, so your Python code will always be somewhere in the computer memory.Cheers,
Maxime -
I am trying to compile the example from the python manual, but it cannot find following include files:
#include "maxon/vm.h"
#include "maxon/cpython.h"
#include "maxon/cpython27_raw.h"Also, it complains about iferr(..) in the init script.
I am using R20.026, windows 10, VC++2017.
-
You need to include the python.framework in your projectdefinitions.txt and regenerate a new vs solution with the projectool.
If the python.framework is already included you may need to do the next things:#include "maxon/vm.h" #include "maxon/cpython.h" #include "maxon/cpython27_raw.h" #include "maxon/cpython_c4d.h" MAXON_DEPENDENCY_WEAK("maxon/vm.h"); MAXON_DEPENDENCY_WEAK("maxon/cpython.h"); MAXON_DEPENDENCY_WEAK("maxon/cpython27_raw.h"); MAXON_DEPENDENCY_WEAK("maxon/cpython_c4d.h");
Regarding your iferr issue, I guess it's related to https://developers.maxon.net/forum/topic/12435/attribute-nodiscard-requires-compiler-flag-std-c-17/13
Cheers,
Maxime. -
I went back to compiling with VC++2015.
python.framework is included.
I added your suggestions, but still it fails.
Despite going back to VC++2015, I also still have the iferr issue.
Here the projectdefinitions.txt
Platform=Win64;OSX Type=Solution // this plugin depends on these frameworks: APIS=\ cinema.framework; \ misc.framework; \ image.framework; \ core.framework; \ python.framework // defines the level of rigour of the source processor's style check stylecheck.level=0 Solution=\ plugins/cinema4dsdk;\ plugins/maxonsdk.module;\ plugins/commandline;\ plugins/CommandLineRendering
-
You have to define the APIS in the
projectdefinition.txt
of your plugin.Not in the
projectdefinition.txt
of the solution.See Project Tool.
-
@PluginStudent said in Reading script file into memory:
You have to define the APIS in the
projectdefinition.txt
of your plugin.Not in the
projectdefinition.txt
of the solution.Great, tht solved it. Thanks!
-
To summarise, there are 2 projectdefinition.txt files.
- on main / sdk level, Define which project (plugins, etc.)
Example:
Platform=Win64;OSX Type=Solution // defines the level of rigour of the source processor's style check stylecheck.level=0 Solution=\ plugins/cinema4dsdk;\ plugins/maxonsdk.module;\ plugins/commandline;\ plugins/CommandLineRendering
- on plugin level, // Configuration of a custom solution in the projectdefinition.txt file
Example:
// Supported platforms Platform=Win64;OSX // Type of project Type=DLL // this plugin depends on these frameworks: APIS=\ cinema.framework; \ misc.framework; \ image.framework; \ core.framework; \ python.framework // Enable some advanced classic API support; not needed for hybrid plugins C4D=true // Plug-in code-style check level stylecheck.level=0 // Custom ID ModuleId=net.maxonexample.commandlinerender
- on main / sdk level, Define which project (plugins, etc.)