Jump to content

alank2

Members
  • Content Count

    176
  • Joined

  • Last visited

  • Days Won

    1

Everything posted by alank2

  1. alank2

    Using a DLL in MSVC

    You have figured it out Remy!!! Good work! Superb!!! Thank you! I added System::Set8087CW(0x133f) to my DLL and rebuilt it in 10.2 - no crash. Remark it out, back to the crash. This brings up a question #1 - is the original value (whatever it was set to before loading the DLL changes it) stored somewhere (could it be Saved8087CW)? I'm not sure I'd want a DLL changing the floating point behavior of a program just because it is loaded. Also, should I do an Application->Initialize() or not in the DllEntryPoint/atttach? Question #2 - What does Application->Initialize() do? int WINAPI DllEntryPoint(HINSTANCE hinst, unsigned long reason, void* lpReserved) { if (reason==DLL_PROCESS_ATTACH) { //Application->Initialize(); //Application->MessageBox(L"test",L"test",MB_OK); System::Set8087CW(0x133f); } else if (reason==DLL_PROCESS_DETACH) { } return 1; }
  2. alank2

    Using a DLL in MSVC

    Is there a way to hit the Quote button and split into multiple quotes you can respond to? >You can call the Form's Update() method to force an immediate repaint. Will try this. >That implies your EXE is calling the DLL functions in a loop that is not processing your UI's message queues in between calls into the DLL. That is not a good design choice, especially for a DLL with a UI. I would suggest either: > moving your DLL's UI into a worker thread with its own message loop. > having the DLL export a function that the EXE can call periodically to pump your UI's message queue. > If the EXE has its own UI, then simply break up the EXE's logic to work asynchronously so its own message loop can also service your DLL's UI. I did have a processmessages function exported that would call processmessages, is this what you mean by the bold suggestion here? >Have you considered using the Remote Debugger? I've never used but, but will have to look into it! >Now we're getting somewhere useful. RAD Studio 12.0 did make changes to how it handles floating-point exceptions: >https://docwiki.embarcadero.com/RADStudio/Athens/en/What's_New#Disabling_Floating-Point_Exceptions_on_All_Platforms >On older versions, sometimes you do need to adjust the exception masks manually. Particularly for MSVC compatibility. How would I do that? Adjust these: Default8087CW, DefaultMXCSR, DefaultFPSCR, and DefaultFPSCR Somehow in the older compiler version?
  3. alank2

    Using a DLL in MSVC

    Also, thanks for the tip about dumpbin and lib to make an import library - that is much easier than what I was doing. I found an example at this link: https://stackoverflow.com/questions/9946322/how-to-generate-an-import-library-lib-file-from-a-dll ... and expanded it to allow specifying an alternate output lib filename, some error checking, and returning an errorlevel: buildlib_msvc.bat One may have to change the dumpbin/lib path (or eliminate it if running from a MSVC developer prompt). @echo off rem check for 2 options only if empty%1==empty goto badopt if empty%2==empty goto badopt if not empty%3==empty goto badopt rem make sure dll exists if not exist %1 goto dlldoesnotexist rem delete old lib file if it exists if exist %2 del %2 if exist %2 goto cantdeleteoldlib rem add msvc path for dumpbin/lib if empty%MSVC_PATH_ADDED%==empty SET PATH=C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.29.30133\bin\HostX86\x86\;%PATH% if empty%MSVC_PATH_ADDED%==empty SET MSVC_PATH_ADDED=yes rem make lib (got this from someones example at stackoverflow) setlocal enabledelayedexpansion for /f "tokens=1-4" %%1 in ('dumpbin /exports %1') do ( set /a ordinal=%%1 2>nul set /a hint=0x%%2 2>nul set /a rva=0x%%3 2>nul if !ordinal! equ %%1 if !hint! equ 0x%%2 if !rva! equ 0x%%3 set exports=!exports! /export:%%4 ) for /f %%i in ("%1") do set dllpath=%%~dpni lib "/out:%dllpath%.lib" /machine:x86 /def: %exports% if errorlevel 1 exit /b 1 rem make sure new lib exists if not exist %1 goto didnotproducenewlib rem rename lib file to specified lib filename ren "%dllpath%.lib" %2 rem remove exp file if exist "%dllpath%.exp" del "%dllpath%.exp" rem success exit /b 0 :badopt echo ERROR: Specify buildlib_msvc name.dll name.lib exit /b 1 :dlldoesnotexist echo ERROR: %1 dll does not exist exit /b 1 :didnotproducenewlib echo ERROR: Did not produce new %2 lib exit /b 1 :cantdeleteoldlib echo ERROR: Can't delete old %2 lib exit /b 1
  4. alank2

    Using a DLL in MSVC

    >They are using the same DLL instance? I probably didn't explain it clearly enough. >That is not how you should make the import lib for MSVC. Use MSVC's command-line DUMPBIN and LIB tools to create a new import lib from the DLL itself. >Use DUMPBIN to create a .DEF file for the DLL's exports, and then use LIB to generate a import lib from the .DEF file. I haven't tried this method yet, but will look into it. >Which items are you referring to exactly? There is nothing "bold" in what you showed. I had bolded the exports I didn't ask for, but it didn't paste in. >You really should not be calling Application->ProcessMessages() at all. I have to or it won't update the form properly. If I just call Show for example and skip the ProcessMessages, it won't paint it properly. If I don't call ProcessMessages, it won't process a click on the cancel button that I can read. >What is the actual crash? What is the error message, verbatim? Does the crash happen while the DLL is being loaded into memory, or inside of DllEntryPoint()? >Have you tried debugging the DLL in the IDE? Configure your DLL project with your MSVC app exe as its Host. Then put breakpoints in the DLL code as needed. >When you run the DLL project, it will execute the MSVC app, which will then load your DLL, and the debugger should attach to it so it can step through the DLL code normally. The application is an annoying one to install and is running in a VM where the compiler is not. I don't want to install it on my dev machine. The error is a code that c000008e that a search says is a floating point divide by zero error. I'm assuming it is just some type of crash. I just built the real DLL (not an empty stub) and with 12.2 it fully works with no problems. With 13.3 it crashes just like it did with 10.3. I have to think they must have fixed something to make it work in 12.2. Thank you for the help - it is greatly appreciated!
  5. alank2

    Using a DLL in MSVC

    I'll need to work through your email questions Remy, but in the meantime, I found that a new DLL (VCL, multithreading) will also fail on all versions I tried until I got to 12.2 and there is does not fail. I'll try to compile it there and see if it works with everything enabled again. cppb6 - fails cppb10.3 - what I was testing on - fails cppb11.3 - fails cppb12.2 - does not fail interestingly - perhaps something was fixed.
  6. alank2

    Using a DLL in MSVC

    Even if I make a brand new empty dll via file->new->other->dynamic library vcl with or without vc++ style dll set. I then set release and set it to link with dynamic rtl=false and link with runtime packages=false, the application will crash if I try to loadlibrary it only (no functions being executed).
  7. I am using TNetHTTPClient and I am getting back a status code 200 from the request. When I look at the value in StatusText however, it is empty instead of the OK I expected. I did the same request with postman and looking at the raw status line the OK is present. Has anyone else experienced this? I did look in System.Net.HttpClient.Win.pas and see that it does a: Result := ReadHeader(FWRequest, WINHTTP_QUERY_STATUS_TEXT); edit: this was with 11.3
  8. Thank you for the help rvk (and everyone in this thread!), instead of a loose end I now have a reason for why it is doing what it does. Going forward I'll ignore the status text always and just go with the result code. What made me nervous about this is that the status code itself is also retrieved from the same function as text and then later converted to an integer, so I'm not sure why this is an issue for status text, but not status code. Hopefully going forward it won't be.
  9. I noticed this as well. I don't usually use the /install or /uninstall options but instead use Inno setup and sc.exe to stop/remove/install/start services. I usually (and I don't think it is the right way as Remy pointed out to me in another thread, I still need to do some testing on it to change) implement a ServiceExecute with a message loop that runs until the service is stopped, so something like this; while (!Terminated) //do not quit if process is running until it is finished { ServiceThread->ProcessRequests(true); Sleep(250); } If I add this to the above service, it doesn't add the OK from local execution of "project1 /install", but it does for some reason for "project1 /uninstall". How would you do this? Exactly. I know the local system account does change the environment that a service runs it as far as rights go, but I don't know what this would have a change in the WinHttpQueryHeaders().
  10. Good thinking!!! This is it. When the service is configured to use "Local System Account" It does NOT report "OK". If I change it to administrators or my own user name, it does report "OK". Any ideas why local system account can't retrieve the status text even though it does properly retrieve the status code?
  11. Here is some test code that shows it. From the application (returns OK properly): From the service (does not return OK properly, but an empty string instead): result 200 '' The service saves to a file "c:\5\log.txt", but you can change where it saves it if you run the code. Build the service, admin cmd prompt, go win32\debug and run project1 /install, then run net start service1. it will create the c:\5\log.txt (or what you renamed it to) with the results of the GET to google. To uninstall just do net stop service1 followed by a project1 /uninstall. test.zip
  12. My big concern isn't the status string, I can ignore it. My concern is that if that is not right, why, and what else might not be right.
  13. Tested it on 10 and 11 same result.
  14. I created a new 10.3.3 service application and put the code in - it does NOT return OK. The same code in a standalone application does return OK. I'll come up with a sample project I can post to see if others can reproduce the issue.
  15. It is not consistent - I have another API that I use in the same service and it returns OK just fine, but if I do a GET @ https://google.com, it will not return OK. I then tried a new application (not service) with the same code (GET @ https://google.com), it works fine and returns OK. I rebuilt the project on 10.3.3, 11.3, and 12.2, and all of them return an empty string instead of OK. I wonder if it being a service has something to do with it. Next up I'll build a new service project service and see if the issue occurs with that.
  16. This is a cut from the postman console which shows what the request returns (at least from postman): Content-Length: 126768 ----------------------------446648698401590502853205 Content-Disposition: form-data; name="select" Static Data ----------------------------446648698401590502853205 Content-Disposition: form-data; name="fileData"; filename="file.json" <file.json> ----------------------------446648698401590502853205 Content-Disposition: form-data; name="id" 1234567 ----------------------------446648698401590502853205-- HTTP/1.1 200 OK Date: Wed, 04 Dec 2024 18:55:06 GMT Content-Type: application/json; charset=utf-8
  17. I think this was not real, but part of the LSize isn't the right value because of a debugger issue. Wouldn't it be encrypted if I captured it with wireshark (https)?
  18. I'm not making a lot of sense out of this windows function. Why would it return a size that doesn't include the terminating null \x00 character? When it returns the buffer, does it not null terminate the string? I'm not sure this is the issue as I modified the LSize to be 200 and let it make the second call and it still returned an empty string. edit: I'm back to why would WinHttpQueryHeaders return a proper 200 string that gets turned into an integer just fine, but not the OK part. Is there any way to access the actual response as bytes to see if it matches my postman test?
  19. The original call to WinHttpQueryHeaders has a LSize==0, and it returns with ERROR_INSUFFICIENT_BUFFER. They intentionally call with a 0 to get the size. It skips by "if GetLastError <> ERROR_INSUFFICIENT_BUFFER then" and moves to SetLength, but now my LSize is 16579768, so clearly the debugger is back to not working right again. Moving to the CPU I can see that is loads EDX with a value 2 which is the size of OK. Then it does a SHR edx,1 and changes the value from 2 to 1. Then a DEC edx which changes it from 1 to 0. So the mystery here is WHY this line: SetLength(Result, LSize div SizeOf(Char) - 1); is dividing by sizeof(Char) which is apparently 2 and then subtracting 1. edit: looking at WinHttpQueryHeaders , it shows: [in, out] lpdwBufferLength Pointer to a value of type DWORD that specifies the length of the data buffer, in bytes Since it is dealing with wide strings, 2 could be a zero terminator for the wide string and it thinks there is nothing to return. Why would this function not see the "OK" in the http response?
  20. It is 32 bit. Removing the two .pas modules and turning on debug dcu's fixes the issue with inspecting LSize. It gets cleared properly now and returning from WinHttpQueryHeaders leaves LSize at 0 which is why it isn't allocating it or retrieving it. The status line in the raw is: HTTP/1.1 200 OK If it makes any difference, I am sending multipart/form-data.
  21. I added the pas files to my project (C++) and stepped to ReadHeader - for some reason I can't evaluate variables properly - if I try to look at LSize even after stepping LSize:=0, it is NOT zero. After calling WinHttpQueryHeaders, it shows as zero. GetLastError is ERROR_INSUFFICIENT_BUFFER and it gets by that test. It does not get by the "if Length(Result) > 0 then " test however making me think that the SetLength() did not change the length? Oddly with the debugger on the "if Length(..." line it now shows the LSize as 274, but the if length test fails and it never calls WinHttpQueryHeaders the second time.
  22. I need to put a VCL form in a DLL and call it from another application. I've made the DLL and can call it just fine, but it shows as maximized even though it isn't supposed to be. //create form Form1=new TForm1(NULL); //show form modally Form1->ShowModal(); //copy result strcpy(APhoneNumber, Form1->phonenumber); //delete form delete Form1; Windows state is set to normal, If I put this in the formshow of the form: Form1->WindowState=wsNormal; There is no difference - I think the WindowState is already set this way. If I could click the title bar of the form, it does go to the right size. If I close it and reopen it with the above code (which creates a new TForm1), it does NOT happen a second time. If I change the formshow to this: Form1->WindowState=wsMinimized; Form1->WindowState=wsNormal; It does show as normal size the first and subsequent times, but I can see the animation of it minimizing and restoring. Why does this happen? Could it be perceiving the way the application that is using it was loaded such as maximized and overriding the WindowState somehow? if so, can that be prevented in a better way that what I'm doing? Other thoughts? edit: Does this have to do with Application->FInitialMainFormState? Can I change it somehow? When I try it says it is protected.
  23. I get an error when I try to use a MP4 for the TMediaPlayer. Even the VideoPlayback sample will not work. I did try to play an AVI and it doesn't error, but it doesn't play correctly either with a lot of visual artifacts. Has anyone run into this before? I found this: https://stackoverflow.com/questions/64844414/register-new-media-codec-in-fmx-media-player-in-c-builder But when I try to #include <FMX.Media.Win.hpp>, I get a ton of errors: [bcc32c Error] Winapi.DirectShow9.hpp(237): use of undeclared identifier 'IDirectShowStream' [bcc32c Error] Winapi.DirectShow9.hpp(491): no member named 'PReferenceTime' in namespace 'Winapi::Dxtypes' ...
×