Jump to content
Larry Ullman's Book Forums

Necuima

Members
  • Posts

    359
  • Joined

  • Last visited

  • Days Won

    7

Everything posted by Necuima

  1. Hi, I found the easiest way to install Image Magick on my Windows 7 PC was to use the installation exe file. It comes in several flavours and I chose the Q16 dll 32 bit dynamic version from http://www.imagemagick.org/script/binary-releases.php#windows It has the latest version but to make it compatible with the PHP dll I had I had to go back to version 6.8.6 which fortunately I had the installation exe for. At one stage I tried to build it from source but I was not able to and it seemed too hard for me anyway. The installation exe was very quick and you have a couple of install option to set - I chose to install the header files but not to associate image files with it. Hope it helps. Cheers from Oz.
  2. Hi, I thought that I would post this as it may be of help to anyone using the Imagick DLL in PHP to access Image Magick functions. In case you are not aware, Image Magick is very function-rich and terrific open source software for image manipulations. My use of it is extremely basic, just to resize jpg images. About a year ago I came across the php imagemagick dll (filename is php_imagick.dll and installed it without any problems. At the time I already had Image Magick installed on my PC. To my delight, I managed to get my resizing to work just fine (previously I had been using the PHP GD library functions). A week or so ago I installed the latest version of Image Magick on my PC. To my horror the PHP functionality stopped working. After some Googling I discovered that your php imagick dll has to align version-wise with your installed Image Magick. So I tried to find the latest php dll but although I found a reasonably current dll it was incompatible with my newly installed Image Magick package. I could not find out how to ascertain the version alignment of the php dll though it is clear what the version number of the Image Magick PC package is. My installation last year was just luck!! I eventually found a more current php imagick dll 'buried' inside the PECL Imagick zip file (available from the web) but it too was not version-aligned with my new Image Magick installation. Luckily I still had the 'old' Image Magick install exe so I uninstalled the new Image Magick and then re-installed the old version and now everything works OK again. One is tempted to comment 'traps for young players' but as I don't qualify for the 'young' tag, I will say that it is 'traps for inexperienced players':-) Cheers from Oz.
  3. OK, I bypassed the problem. I still don't know exactly what the problem was but it certainly is to do with the 'funny' function name "MathFuncs::MyMathFuncs::Add". My 'bypass' was to develop another DLL without the class structure of the MSDN example and it works just fine :-) I learned a few things along the way! To create a Windows DLL in Visual C++ there are a couple of pointers to note: - after all the normal includes, you 'tell the world' that this module is exporting a function for use by others. At first the term 'export' confused me but it seems to just mean that the function will be available to the outside world. The statement in my case is: #define export extern "C" __declspec (dllexport) - You can have functions within your DLL that are not visible to the outside world and they are just 'ordinary' C++ functions. - The function that needs to be made visible to the outside world, i.e. the one that is to be 'exported' needs to have it's name so that it won't get 'mangled' by the C++ compiler. So you include all that function's code within an 'extern' statement - in my case: extern "C" { then the beginning of the function itself: export int functionName(LPCSTR fileName, int param1 = 80, int param2 = 1000) .... ... and at the end: } //end of C extern The module that will call this dll function also needs some 'special' code - note that I am calling the dll explicitly - calling it implicitly is different and an example can be found in the MSDN tutorial mentioned above. So for the explicit call, after the usual includes I have: typedef int (__cdecl *MYPROC)(LPCSTR, int, int); As far as I understand, it states that this module will use an explicitly called DLL which will receive an LPCSTR and two ints as inputs and will return an int. I hope that this will be of help to some poor soul who, like me, Googled for literally weeks before finally getting this to work, and there was a lot of trial and error involved. But it's nice to have gained some understanding of DLLs and their use:-) Cheers from Oz. P.S., my environment for this is Windows 7, 64 bit and Visual C++ 2008 Express Edition.
  4. Hi, Yes I usually read introductions :-) Cheers from Oz!
  5. Thanks Larry. My plan is to go back to basics and properly learn C++ (from your book and one which specifically targets the Visual C++ IDE that I am starting to use). If I ever figure it out, with your permission I could post the solution! Best wishes from Oz.
  6. OK, I have managed to prove that the general approach works fine for a different dll file so it must be something to do with this specific dll and the ::s in "MathFuncs::MyMathFuncs::Add". I just don't understand this well enough I guess but at least I've been able to show that the general explicit call approach can work in my environment (Windows 7, 64bit). Thanks for anyone who looked at this and pondered how to help! Cheers from Oz.
  7. Necuima

    Long Time, No See!

    Happy Thanksgiving to North American forum members! We don't celebrate it in Australia but hear about it from our news broadcasts from your fair countries. Cheers from Oz.
  8. Hi again, as far as I can see, I am doing things right but GetLastError() indicates that the procedure name can't be found - the exact error is "GetProcAdsdress failed with error 127: the specified procedure could not be found". OK, that's clear enough, but when I look at the dll file with DLL Export Viewer, it shows that a procedure with this name is there. The exact name that DLL Export Viewer shows is "public static double __cdecl MathFuncs::MyMathFuncs::Add(double, double)" with ordinal 1. Surely I don't have to key all that in? I have also tried to get the address of the procedure using the ordinal approach and while something is found, it does not seem to be the "Add" function in the dll as 10 + 10 = -SomeHugeNumber!! To use the ordinal approach I followed some advice in StackOverflow: int ordinal = 1; and then in the GetProcAddress: ProcAdd = (MYPROC) GetProcAddress(hinstLib, (LPCSTR) ordinal); Again, any help/ideas will be most appreciated! This is starting to drive me insane!!
  9. Re the explicit linking call to the dll - I feel (hopefully not being delusional) that I'm close. At least the LoadLibrary is loading the dll now. But I'm having trouble getting the address of a function in the dll. I can see that the dll indeed has functions (from the MSDN C++ IDE) but I can't seem to get the function name OK. Here's a code snippet of my GetProcAddress try: ProcAdd = (MYPROC) GetProcAddress(hinstLib, "MathFuncs::MyMathFuncs::Add"); // If the function address is valid, call the function. if (NULL != ProcAdd) { ...... I've tried "Add" on its own and various other combinations. Here's the .h file which I understand defines the function to the outside world: // MathFuncsDll.h #ifdef MATHFUNCSDLL_EXPORTS #define MATHFUNCSDLL_API __declspec(dllexport) #else #define MATHFUNCSDLL_API __declspec(dllimport) #endif namespace MathFuncs { // This class is exported from the MathFuncsDll.dll class MyMathFuncs { public: // Returns a + b static MATHFUNCSDLL_API double Add(double a, double ; // Returns a - b static MATHFUNCSDLL_API double Subtract(double a, double ; // Returns a * b static MATHFUNCSDLL_API double Multiply(double a, double ; // Returns a / b // Throws const std::invalid_argument& if b is 0 static MATHFUNCSDLL_API double Divide(double a, double ; }; } As always, any suggestions will be most welcomed! Cheers from Oz.
  10. OK, I finally found a step-by-step guide on creating a DLL and then using it for a Visual C++ IDE. And it works!! Sorry if I have wasted anyone's time - please ignore the post above! If you're interested the link I found is http://msdn.microsoft.com/en-us/library/ms235636.aspx The example uses implicit linking - I will now try and modify it to use explicit linking!! Cheers from Oz.
  11. Hi Radoslava, Many thanks for your reply and advice. I am trying to re-build the dll in VC++ 2008 EE but to be honest do not really know what I'm doing!! Here's my code: #include "stdafx.h" #define export extern "C" __declspec (dllexport) // this is the entry point to the dll BOOL APIENTRY DllMain (HINSTANCE hInst /* Library instance handle. */ , DWORD reason /* Reason this function is being called. */ , LPVOID reserved /* Not used. */ ) { switch (reason) { case DLL_PROCESS_ATTACH: break; case DLL_PROCESS_DETACH: break; case DLL_THREAD_ATTACH: break; case DLL_THREAD_DETACH: break; } /* Returns TRUE on success, FALSE on failure */ return TRUE; } //Tell the c++ compiler to switch to standard C compiling so exported function names are not mangled extern "C" { //passing incoming string to MessageBox export double printString(LPCWSTR string) { //Return the string that the calling program passed to this function in a MessageBox. return (double) MessageBox(0,string,L"Sample Print String Function", 0); } } //end of C extern I got this code from another post somewhere - it worked for me once but now I can't even get it to compile in the Dev-C++ IDE!! My lack of knowledge in this area would fill volumes! The compiler error that I'm getting is unresolved external symbol _WinMain@16 referenced in function ___tmainCRTStartup and .......\VS_2008_DLL\Debug\VS_2008_DLL.exe : fatal error LNK1120: 1 unresolved externals Any help will be most appreciated! Cheers from Oz.
  12. Necuima

    Long Time, No See!

    Hi Hartley-san, Your post above is also very interesting - thanks for sharing. Mostly when I went to Japan I flew from Sydney to Narita on a Sunday night over-nighter, then worked in the Tokyo office with English-speaking colleagues and then back home again on the Thursday night overnighter to Sydney and then a connect to Melbourne where we lived at the time. Sadly I only learned a few words of Japanese though I tried. I have found that I can learn things fairly quickly but if I don't use them I also forget them equally as quickly. Take the Autocoder language that I learned in the late 60s - apart from the language's name, I can't remember a single thing about it other than programs written in it ran on the 1401 mainframe - cards in, printed paper out. Once I had to stay in Japan over the weekend and I treated myself to a ride on the Shin Kan Sen to Kyoto and back - wow - what a ride!! The Japanese people that I worked with were wonderful and often took me out to dinners where I ate and enjoyed many un-Western dishes:-) Usually washed down with Sapporo and a little sake! Thanks also for your comments on my current C++ post - I don't think that the problem is within the DLL per se, but in the C++ LoadLibrary statement in the simple C++ program that is trying to call the DLL. I have Googled till I'm blue in the face but to no avail!! Again, thanks for sharing. Cheers from Oz.
  13. Necuima

    Long Time, No See!

    Hi Hartley-san, I always think of Japan when I see your name - I used to go to Tokyo quite often on business in the late 90s and I was "Eric-san". Thank you for your interest - I started in computers programming an IBM 1401 mainframe in a language called Autocoder - that was in 1967. Then I progressed to Cobol, and IBM 360 Assembler. From the mid-70s we started to get into mini-computers for basically stand-alone systems with just tape interfaces to the company's mainframe. Then in then 80s came PCs and I got my first IBM PC in about 1983. It always amazes me that there is more computing power in my desktop PC here at home than in those old mainframes which were monsters! Later in my career I was in technical management and had to leave the 'hands-on' programming behind. But now as a retiree I can program to my ability's content and learn, learn, learn. So you and fellow forum respondees and Larry and his books are a great help to me and enjoyment when I can get something to work! In another post you will see my latest technical dilemma in C++ which I still have not resolved despite many hours of Googling! Best wishes from Oz.
  14. Necuima

    Long Time, No See!

    It is interesting to read about some of the regular forum members, many of whom have helped me along my 'learning way' (Thanks again!!). I gather that OSU is Ohio State University (Hartley-san). As an Aussie, in my younger years, I went to the University of Melbourne and then did a Master's in Computing at Monash University. In my retirement I am trying to keep my ageing grey cells active and learn some of the newer technologies which in my case is just about everything web! For me it is a fascinating and often challenging hobby. I always appreciate the help that all of you and Larry give me. Best wishes from Oz.
  15. Further thought - I suppose that it is possible that the Express version of Visual C++ 2008, which I am trying to use, does not support this?? But I can't find any evidence to support that conjecture! To quote the King of Siam 'Tis a puzzlement" !! Cheers.
  16. Hi again, Just a point of clarity - the error is not occurring in the DLL, it is occurring in the module (code above) which tries to call the DLL. If I can get past this, then we'll see if the DLL works OK when called by a MS Visual C++ executable rather than the one created by Dev-C++ (which as mentioned, works fine). Cheers, and thanks for the interest.
  17. Hi Larry, OK, I set a break point and ran it in debug mode and lo and behold the LoadLibrary statement fails with error "CXX0030: Error: expression cannot be evaluated". It is a bit of a mystery to me why the Dev-C++ executable, which executes exactly the same LoadLibrary statement as the Visual Studio version, works just fine yet the VS one gives this error. I will Google it further. Cheers from Oz.
  18. Hi Larry, It compiles OK but the execution fails with the "Unable to call the dll" message. I have tried single forward slashes in the LoadLibrary statement instead of the double back-slashes but the outcome is the same. In the Dev-C++ version it uses forward slashes but the Visual C++ seems to need the double back-slashes. I have triple-checked and the DLL is definitely there. My admittedly meagre understanding of DLLs is that it does not matter how they were created as long as they function correctly and are called correctly. The DLL called by the code above was developed on my PC in Dev-C++ and simply prints out the string passed to it in a message-box. I did this to try and learn a little about DLLs - how they are created and how they are used. Please correct me if my understanding is not correct, e.g., do I need to compile the DLL in Visual C++ as well? I will keep pursuing this as it's a complete mystery to me!! Again, any advice/suggestions will be most welcome. Cheers from Oz.
  19. Hi, Can someone please help me with this code which just calls a DLL. The code works perfectly in the Dev-C++ IDE but gives me an error indicating that the LoadLibrary/GetProcessAddress fails when I try to execute it in the MS Visual C++ (2008 express) IDE. // A simple program that uses LoadLibrary and // GetProcAddress to access the printString function from HelloWorld_CPP.dll. // It also calls the function in the DLL passing a string to it. #include <stdafx.h> #include <windows.h> #include <stdio.h> #include <iostream> #include <string> #include <comdef.h> // needed to use LPCSTR typedef int (__cdecl *MYPROC)(LPCSTR); /* LP == long pointer. Just think pointer or char* C = const in this case I think they mean the character string is a const, not the pointer being const. STR is string (UTF-8 I think (one byte per character)) */ LPCSTR getInputString(void) { std::string theString; // define the variable to hold the string // std::cin.ignore(100, '\n'); // clear out the input buffer std::cout << "Enter the string\n"; std::getline(std::cin, theString); // get a whole sentence LPCSTR newString = theString.c_str(); // convert the entered string to LPCSTR format return newString; } int main(void) { HINSTANCE hinstLib; MYPROC ProcAdd; BOOL fFreeResult, fRunTimeLinkSuccess = FALSE; // Get a handle to the DLL module. hinstLib = LoadLibrary(TEXT("E:\\Documents\\Visual Studio 2008\\Projects\\DLL_Test\\HelloWorld_CPP.dll")); // If the handle is valid, try to get the function address. if (hinstLib != NULL) { ProcAdd = (MYPROC) GetProcAddress(hinstLib, "printString"); // If the function address is valid, call the function. if (NULL != ProcAdd) { fRunTimeLinkSuccess = TRUE; // OK, now get the string from the user console LPCSTR aString = getInputString(); (ProcAdd) (aString); // (ProcAdd) ("Message sent to the DLL function"); // the string that gets 'sent' to the function in the dll } // Free the DLL module. fFreeResult = FreeLibrary(hinstLib); } // If unable to call the DLL function, use an alternative. if (! fRunTimeLinkSuccess) { printf("Unable to call the dll\n"); std::cin.get(); return 1; } } The environment is Windows 7, 64 bit. Any assistance will be most appreciated. Best regards, Necuima.
  20. Hi, after much Googling and trial and error I managed to create the dll in C++ (rather than my first attempt above in C). The C++ dll works! Thanks to anyone who had a look at this. Cheers from Oz.
  21. Hi, I hope that this is not 'too simple' for anyone replying, but I'm a C novice so your advice will be most appreciated. The background is that I'm trying to learn about DLLs and using them in a Windows 7 environment. I have created a simple 'HelloWorld-ish' DLL in C which compiles OK. It is meant to receive a string passed to it from a calling C++ program and display that string in a messagebox. I am aware that strings are handled differently in C and C++. I suspect that my 'caller' program is passing the string OK but that my C DLL is not handling it OK. The DLL displays just the first character of the passed string. Here's the code from the DLL - first the dll.h: #ifndef _DLL_H_ #define _DLL_H_ #if BUILDING_DLL # define DLLIMPORT __declspec (dllexport) #else /* Not BUILDING_DLL */ # define DLLIMPORT __declspec (dllimport) #endif /* Not BUILDING_DLL */ DLLIMPORT void HelloWorld (char *str_in); #endif /* _DLL_H_ */ And the HelloWorld.c code: #include "E:/documents/C_PlusPlus/HelloWorld_C/dll.h" #include <windows.h> #include <stdio.h> #include <stdlib.h> DLLIMPORT void HelloWorld (char *str_in) { MessageBox (0, str_in, "Try 2", MB_ICONINFORMATION); } BOOL APIENTRY DllMain (HINSTANCE hInst /* Library instance handle. */ , DWORD reason /* Reason this function is being called. */ , LPVOID reserved /* Not used. */ ) { switch (reason) { case DLL_PROCESS_ATTACH: break; case DLL_PROCESS_DETACH: break; case DLL_THREAD_ATTACH: break; case DLL_THREAD_DETACH: break; } /* Returns TRUE on success, FALSE on failure */ return TRUE; } My environment in this context is Windows 7 64 bit and Dev-C++ I have scoured the Internet and forums but I can't seem to find what I'm looking for. Any advice will be most appreciated and thank you in anticipation. Cheers
  22. Thanks HartleySan, your advice is always appreciated. Cheers from Oz.
  23. Hi, I have a form field that needs to be validated before any attempt is made to upload the contents to a database. Fear not, the test is performed again in PHP before the db update! I am using jQuery and the associated jQuery form validation module. Everything works fine but I have found that three slightly different regular expression tests can be used - my question is: are there any performance or other reasons why one particular approach is best? Here's the code together with an explanation of the regex: $.validator.addMethod( "details_OK", function (value, element) { var valx = String(value); // var regex_tester = new RegExp( var regex_tester = /^(http:\/\/)(\S)+(\?u=){1}(\S)+(\&id=){1}(\S)+(\&e=){1}(\S)+/; /* var regex_tester = / // must start with what follows "^" + // now the http bit... "(http:\/\/)" + // any letters, numbers or periods (one or more of them) "(\\S)+" + // must contain ?u= (once) "(\?u=){1}" + // now more letters, numbers etc.. "(\\S)+" + // now &id= (once) "(\&id=){1}" + // now more letters, numbers etc.. "(\\S)+" + // now &e= (once) "(\&e=){1}" + // now more letters, numbers etc.. "(\\S)+" + /; */ // Note: all 3 of the following tests work OK... // if (regex_tester.test(valx)) // if (/^(http:\/\/)(\S)+(\?u=){1}(\S)+(\&id=){1}(\S)+(\&e=){1}(\S)+/.test(valx)) if (valx.match(/^(http:\/\/)(\S)+(\?u=){1}(\S)+(\&id=){1}(\S)+(\&e=){1}(\S)+/)) return true; else return false; }, "Error - The Internet address (URL) does not have some of the required/expected details." ); // end details check I could not get the "...new RegExp approach to work thus it is commented out. Any thoughts/advice will be most appreciated. Thanking you in anticipation, Cheers from Oz.
  24. Hi Jerry, I did not see this earlier but here's an example of accessing a JavaScript function from within PHP... First, the function - note that it has a built-in fadeout so the redirection takes 5 seconds whilst fading - it also uses jQuery: function redirect() { $('#fadeout_area').fadeOut(5000); setTimeout(function() { window.location.replace('./index.php?p=whatever'); }, 5000); } now the PHP invocation of the JS function: echo '<script type="text/javascript">', 'redirect();', '</script>'; Hope it helps. Cheers from Oz.
  25. Hi, escape_data() is a function that you define in one of your scripts. I have seen various versions of this function but my understanding is that the function tests which environment you are running in and then applies the appropriate PHP escape_data_string function to the data. So one is a function you define, the other is a standard PHP function (or method in your case above). Please correct me if my understanding is not correct. Cheers from Oz.
×
×
  • Create New...