How to download a file from the internet? [SOLVED]
-
On 06/10/2014 at 14:10, xxxxxxxx wrote:
You can statically compile libCurl and then link the static lib. That way you do not need to include the dll when you ship your plugin.
-
On 06/10/2014 at 14:41, xxxxxxxx wrote:
Could it be that that is what is happening when I compile in Xcode?
My plugin is running perfectly on my Mac, accessing the internet and checking for the file in a protected folder.
And I haven't copied any library into my plugins folder or to the Maxon folder. -
On 06/10/2014 at 15:30, xxxxxxxx wrote:
That sounds like a logical assumption to me.
It's nice that Macs have that set up for you. PC's require most things to be installed by hand.
On the other hand. If someone does all of the work for you. You never learn how to do it yourself.
Which is why Python is both wonderful & evil.-ScottA
-
On 06/10/2014 at 16:37, xxxxxxxx wrote:
But, for the specific case of plugins it is so nice.
I'm having all this trouble because I devised a method to protect my plugins. It is not perfect (no method is) but it makes me more in control and makes life harder for hackers.
It was relatively simple to implement on my Mac. It is a nuisance that it proves to be so complicated on Windows (never really liked Windows very much and this only makes it worse ) -
On 07/10/2014 at 07:38, xxxxxxxx wrote:
Out of curiosity.
How are you converting the curl output to a C4D String type result in your Mac version?
The callback method I posted works. But it looks kind of ugly to me. And I'm wondering if there's a simpler way.-ScottA
-
On 07/10/2014 at 07:58, xxxxxxxx wrote:
Here is my code:
// // access_url.cpp // PolyPaintTag // // Created by Rui Batista on 6/10/14. #include "access_url.h" #ifdef _WIN32 #include <curl.h> #endif #ifndef _WIN32 #include <curl/curl.h> #endif #include <string> using namespace std; // *************************************************************** struct MemoryStruct { char* memory; size_t size; }; // *************************************************************** static size_t WriteMemoryCallback(void *contents, size_t size, size_t nmemb, void *userp) { size_t realsize = size * nmemb; struct MemoryStruct *mem = (struct MemoryStruct * )userp; mem->memory = (char* )realloc(mem->memory, mem->size + realsize + 1); if(mem->memory == NULL) { /* out of memory! */ printf("not enough memory (realloc returned NULL)\n"); return 0; } memcpy(&(mem->memory[mem->size]), contents, realsize); mem->size += realsize; mem->memory[mem->size] = 0; return realsize; } // *************************************************************** bool check_online(string folder,string reg, string username) { CURL *curl; CURLcode res; char *passcode=new char[usrpass.length()+1]; for(long i=0;i<usrpass.length()+1;i++) { passcode[i]=usrpass[i]; passcode[i+1]='\0'; } bool success=true; struct MemoryStruct chunk; chunk.memory = (char* ) malloc(1); /* will be grown as needed by the realloc above */ chunk.size = 0; /* no data at this point */ curl = curl_easy_init(); if(curl) { string baseurl="www.my_url.com"; string usrpass="username:password"; char *the_url=new char[baseurl.length()+1]; strcpy(the_url, baseurl.c_str()); curl_easy_setopt(curl, CURLOPT_URL, the_url); curl_easy_setopt(curl, CURLOPT_HTTPAUTH, CURLAUTH_ANY); curl_easy_setopt(curl, CURLOPT_USERPWD , passcode); curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteMemoryCallback); curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void * )&chunk;); curl_easy_setopt(curl, CURLOPT_USERAGENT, "libcurl-agent/1.0"); /* Perform the request, res will get the return code */ res = curl_easy_perform(curl); /* always cleanup */ curl_easy_cleanup(curl); if (chunk.size!=10) success=false; else if(chunk.memory) { char *b=new char[2]; for(long i=0;i<10;i++) { string a=reg.substr(i,1); b[0]=chunk.memory[i]; if (a!=b) success=false; } free(chunk.memory); } delete [] the_url; /* Check for errors */ if(res != CURLE_OK) success=false; } delete [] passcode; return success; }
I changed a few things to protect my methods of checking the serialization.
However, you end up with a struct containing the bytes that were read and a count of the bytes read.
Assuming the chunk is a struct of type MemoryStruct, I guess it is just a matter of doing something like:char *my_string=new char[chunk.size+1]; for(long i=0;i<chunk.size;i++) { my_string[i]=chunk.memory[i]; my_string[i+1]='\0'; }
-
On 07/10/2014 at 08:06, xxxxxxxx wrote:
Ok. Thanks.
You're using the same callback.
I was just curious if you were doing it a different way.Are you done now?
All problems solved?-ScottA
-
On 07/10/2014 at 08:15, xxxxxxxx wrote:
I had to pause for a while due to "real-life" work
But I was getting all the errors when compiling for Win32.
When I compiled for x86, all errors stopped. I still have to test out.
Just picture this: I finally compiled without the errors and, all of a sudden, the phone rings and a complex and urgent illustration just arrives.
Damn!!! I must finish it to get back to my plugin (I can't have all the required apps opened for the illustration and Windows, at the same time)
Oh, by the way, do I only need to compile for x86?
Otherwise, I will have to install another version of curl also and do some conditional compiling -
On 07/10/2014 at 08:29, xxxxxxxx wrote:
I think you'll need both.
When I tried to use my 32bit version of curl in a 64 bit C4D plugin. That's when I got strange unresolved errors from the init() function.
So I'm guessing that you'll need to have both versions of curl built. And then point to the bits version of curl that matches your C4D plugin bits version.-ScottA
-
On 07/10/2014 at 08:43, xxxxxxxx wrote:
Oh... so much more complicated in Windows
How can I query for which version is being compiled. What are the preprocessor definitions?(in the meanwhile, I have to go and finish my illustration).
-
On 07/10/2014 at 09:25, xxxxxxxx wrote:
I've never used them.
But this is what I'm seeing on stack overflow about it:#if _WIN64 #include <windows.h> #include <your x64 curl folder here> #else #include <windows.h> #include <your Win32 curl folder here> #endif
-ScottA
-
On 07/10/2014 at 11:31, xxxxxxxx wrote:
Ok, just had a little time to test this and when I start Cinema4D in Windows with my plugin in the plugin folder, I get:
The program can't start because libcurl.dll is missing from your computer. Try reinstalling the program to fix the problem.
When I hit OK, Cinema4D starts but, of course my plugin doesn't gets loaded.
I tried to place the libcurl.dll next to the Cinema4D executable and the same happens. I also tried to place the libcurl.dll in my plugin folder but the same happens
This is getting quite frustrating. -
On 07/10/2014 at 11:40, xxxxxxxx wrote:
make sure you are placing the "correct" libcurl.dll !!!. if you compile with 64 bit libraries, then you will need to put 64 bit dlls, or they won't get "seen"
-
On 07/10/2014 at 12:20, xxxxxxxx wrote:
Ok, placed the correct libcurl.dll in the Cinema 4D folder.
Started Cinema 4D, and it told me that the libssh2.dll was missing.
I also added that to the Cinema 4D folder.
Started Cinema 4D again. Now it is asking for MSVCR120.dll
I can't even find that .dll -
On 07/10/2014 at 12:25, xxxxxxxx wrote:
MSVCR120.dll should be installed with VS 2013 , it is Microsoft Visual C++ compiler release 12, you can download it from google
-
On 07/10/2014 at 12:50, xxxxxxxx wrote:
Thank you, MohamedSakr.
I did found it online.
Ok, now Cinema 4D starts without errors. But my plugin doesn't even start.
I placed GePrint's all over the place, mainly in the main.cpp, even before calling all my serialization stuff and nothing gets printed in the Console. -
On 07/10/2014 at 12:53, xxxxxxxx wrote:
this needs code revision , test it in a step by step way, so GePrint in the plugin init function to check, test print after every line, till you find which line stops the plugin
-
On 07/10/2014 at 12:55, xxxxxxxx wrote:
a better approach "but in your case this will look much harder" , compile in "debug" , and step by step, this will need you to learn how debugging work in C++ "and specially in Visual Studio"
-
On 07/10/2014 at 13:31, xxxxxxxx wrote:
Well, I did found out how to debug in Xcode. It is quite simple.
But, in Visual Studio, everything is so much more complex. No auto-completion, no warnings as I type, no suggestions, cryptic errors messages, etc.
I guess I will the GePrint method first, to test out everything. -
On 17/10/2014 at 13:00, xxxxxxxx wrote:
Hi guys,
I see you're having some difficulty with the Windows specific software development environment. Although I'm a bit surprised there doesn't seem to be the equivalent problem on Macs, I'll try to clear it up:
At a high level, consider 32 bit vs. 64 bit, release vs. debug. Multiply them out to get four target combinations. For instance, using "32 bit release compiled, dynamically linked 3rd party SDK files" means you have to copy the 32 bit release DLLs from the 3rd party SDK's file set into the C4D directory that you copy your dependent plugin files. If you instead copy any of the debug DLLs, or the 64 bit release DLLs, it won't work. You can't mix 32 and 64 bit code, they're different platforms, meaning the instruction sets are noticeably different. The files across the four combinations generally won't compile together, link together, nor run mixed up together.
Note: you may hear of some Frankenstein situations, especially mixing release and debug, but they come along with maintenance problems and have major limitations.
So the valid standard combos are:
32 bit debug
32 bit release
64 bit debug
64 bit releaseStatic vs. dynamic
Static linking means the library's code is embedded into your executable. You pay a price by bloating your executable, among other things, and is only a good idea in limited situations.
In contrast, dynamic linking means your executable is setup by the linker to seek out and load one or more separate files (DLLs) when executed, and those DLLs will seek out DLLs they are dependent on, and so on, until all required files are loaded. The catch is that Windows will only look in certain directories, not search across your entire hard disk (or beyond) for them (the rules for the search are explained in MSDN). The most reliable and straightforward way to make sure it can find them is to include them alongside your C4D plugin executable. This is when you must also align the 32 / 64, release / debug factors to copy the right version of the DLLs. Any mismatch will lead to failed execution or similar grief.
The only other factors that you can add per category (or create additional categories) is when you start mixing compilers (ex: Microsoft / Intel), hybrid targets (release with selective debug executables), etc. However, that's when you multiple out the pain of maintaining all the compilation/link target combinations. Of course, you can't escape versioning, but you usually control the SDK upgrade and maintain the same targets.
A big exception is made for Microsoft's runtime DLLs: you have to install them from the correct VC redistributable for each target. Again, 32 / 64, release / debug, and their specific versions are all factors, with the added complication that they purposefully don't create debug redistributable installers. You must install the compiler to get them on a system, copy them manually alongside your executable (ugly / brute force), or create an installer from them yourself (advanced topic, best you look it up if you REALLY need to go there).
As for the nitty gritty details and comparisons (advantages vs. disadvantages of static vs. dynamic), I suggest you read the Wikipedia entries, as it would be too long to summarize here.
My 2 cents,
Joey Gaspe
SDK Support