Jump to content

Dave Nottage

Members
  • Content Count

    1424
  • Joined

  • Last visited

  • Days Won

    32

Everything posted by Dave Nottage

  1. You might have to provide a reproducible test case, because I'm unable to reproduce the problem. I deployed a couple of example PDF files in the app, using the default remote path of /Contents/MacOS/Startup, and used this code to load them: procedure TForm1.OpenPDF(const AFileName: string); var LSourceName, LDestName: string; begin // Bit of a "hack" to get the exact paths of the pdf files deployed to /Contents/Resources/Startup LSourceName := TPath.GetDirectoryName(ParamStr(0)); LSourceName := TPath.Combine(StringReplace(LSourceName, '/MacOS', '', []), 'Resources/Startup/' + AFileName); LDestName := TPath.Combine(TPath.GetTempPath, 'open.pdf'); // Delete any existing temp file TFile.Delete(LDestName); // Copy from resources to common location TFile.Copy(LSourceName, LDestName); WebBrowser1.Navigate('file://' + LDestName); end; Works every time. My guess is that the problem is with your file retrieval/copy, rather than it being a WebBrowser issue
  2. I'll take a look into this.. hopefully in the next few hours. If there's a QP entry, please let me know
  3. Given one of the answers in the SO link, it sounds (pun intended) like AudioServicesPlaySystemSound is your best bet to ensure it works on all devices. You just need to import the function, something like this: uses iOSapi.CoreFoundation; const libAudioToolbox = '/System/Library/Frameworks/AudioToolbox.framework/AudioToolbox'; procedure AudioServicesPlaySystemSound(inSystemSoundID: UInt32); cdecl; external libAudioToolbox name _PU + 'AudioServicesPlaySystemSound';
  4. How are those lines entered? If by typing, why not just type the commas as the code is being typed? If they're generated, why not generate the lines with commas in the first place?
  5. Dave Nottage

    My android app restarts on permission request

    Have you traced through the code to see where it fails? Does it reach the first line in the anonymous method?
  6. Dave Nottage

    Did anybody have the guts to try XCode 10.2

    I use a macOS VM (on a macOS host) to try out new versions of Xcode, macOS etc. No problems at all using Xcode 10.2 with: Debugging to an iPhone X Deploying an app store version (i.e. set Configuration to App Store, use Deployment Manager to deploy)
  7. Dave Nottage

    Delphi 10.3.1 keep deploying corrupted apk

    What version of build tools are you using? i.e. in the Delphi SDK Manager, what is the path for example, for aapt.exe?
  8. Dave Nottage

    Delphi 10.3.1 keep deploying corrupted apk

    Can you be a bit more explicit about what you are actually changing? Preferably, show the before and after, even if it's the whole manifest.
  9. Dave Nottage

    GExperts module to make the Components structure view PERMANENT

    I expect this may be rather difficult to be implemented in an expert without having it totally separate from the Structure View itself, because there is only one TVirtualStringTree which reloads, dependent on whether Code or Design is selected.
  10. Dave Nottage

    Compiling code originally for VS in C++Builder

    Neither of those compile, giving the same error: Declaration terminated incorrectly. It compiles OK omitting: extern "C", however the Load function is not exported, either. Could this be due to the .lib not being linked? I can name Load as Loadx instead, and the project still compiles. I'm using ObjConv from here: https://agner.org/optimize/ to convert the original .lib file to OMF format. C++Builder does not complain about the file being linked, however I'm wondering whether it is sufficient for it to use.
  11. Please specify what version of Delphi (if different to your tagged version of 10.2 Tokyo), Xcode, iOS SDK, and iOS on the device.
  12. Dave Nottage

    Compiling code originally for VS in C++Builder

    Having trouble with the declaration: extern "C" __declspec(dllexport) int Load(pLink: PDLLLINK); Gives: Declaration terminated incorrectly.
  13. Dave Nottage

    Compiling code originally for VS in C++Builder

    Yes, so we'll give that a shot; thanks!
  14. Dave Nottage

    Compiling code originally for VS in C++Builder

    The trick here is that the function that needs to be exported from the DLL is actually in the .lib. Is it possible to use extern "C"' and __declspec(dllexport) with it?
  15. Dave Nottage

    Compiling code originally for VS in C++Builder

    OK, we're a step closer. The DLL compiles, however now I need to export a function contained in the .lib, namely: Load. I've created a .def from a VS C DLL that I know works: LIBRARY WSCTX.DLL EXPORTS Load @1 ; Load ..and added it to the project, however I now receive this error: [ilink32 Error] Invalid command line switch for "ilink32". Parameter "ItemSpec" cannot be null. Either my Google-fu has once again disappeared, or I seem to be alone in ever receiving it using C++Builder?
  16. Dave Nottage

    Compiling code originally for VS in C++Builder

    First one is: "[bcc32c Error] Api_HpcCallTable.h(181): pasting formed '->Hpc_Trace_AddClassId', an invalid preprocessing token" for this code: int HPC_CALL_TABLE_STUB( Hpc_Trace_AddClassId, (char* pszClassName), pszClassName); Where HPC_CALL_TABLE_STUB is defined as: #define HPC_CALL_TABLE_STUB( FuncName, ParamType, ...) \ __inline static FuncName##_Stub ParamType \ { \ if(g_pHpcCallTable && NULL != g_pHpcCallTable->##FuncName) \ { \ return( (g_pHpcCallTable->##FuncName)(__VA_ARGS__)); \ } \ \ return( 0); \ } Great questions. I am using C++Builder 10.3.1 Community Edition. Am I able to choose a different compiler depending on the situation? If so, how? As advised, I created a DLL project and chose C as the language. I have extremely limited experience with C++Builder That seems logical to me. The issue here is that C++Builder will not link to the .lib file as-is, and I assume it's because it's in COFF format. I tried to use COFF2OMF to convert it, however that does not appear to produce a .lib that contains all the required code
  17. Dave Nottage

    10.3.2 as next or waiting for 10.4?

    https://community.embarcadero.com/article/news/16638-rad-studio-august-2018-roadmap That was the last roadmap published. If unchanged, there are things slated for 10.3.x that were not included in 10.3.1, so they may end up in a 10.3.2 release, e.g: macOS 64
  18. Dave Nottage

    Erro 10.3.1 java.lang.IllegalStateException

    Thanks! Given the code in TAndroidHTTPClient.DoExecuteRequest, it would seem that somehow a connection is being made before DoExecuteRequest is executed, because setRequestProperty is definitely called before connect (and it is the only place connect is called). It might be that DoExecuteRequest is somehow being called twice, however I could not say without a test project.
  19. Dave Nottage

    Erro 10.3.1 java.lang.IllegalStateException

    I referred to the callstack, not the actual code. The Callstack window is the one in the very top left of your first picture. It's possible to copy/paste what is inside that window.
  20. Dave Nottage

    Erro 10.3.1 java.lang.IllegalStateException

    When the crash occurs as per your first image, can you click "Break", so that the callstack shows, please? Then present here what the callstack actually shows (preferably paste the text, rather than a picture)
  21. A while ago, I managed to make the whole Citrix Virtual Channel thing work, i.e. I constructed a C DLL much like the examples from the Virtual Channel SDK, and just "re-route" the calls to a DLL written in Delphi (long story short: so far it has been the only way I could make this work). The problem now is that on some machines, the Citrix startup sequence fails, and I'm at a loss as to why. The normal sequence goes like this: A user starts an app from within the Citrix environment Citrix checks which virtual channels are registered with the system, which includes ours (the DLL that is "registered" with Citrix is the C-based DLL) Citrix loads the C-based DLL, and calls the DriverOpen function The DriverOpen function in the C-based DLL loads the Delphi DLL and obtains the method address for the corresponding DriverOpen function in the Delphi DLL The C-based DLL calls the DriverOpen function in the Delphi DLL, the Delphi function "does its thing", and returns the value back to the C-based DLL, which passes that result back to Citrix. The next part of the sequence is that Citrix calls 2 other functions, DriverSetInformation and DriverInfo. These are "re-routed" in the same manner as DriverOpen The problem is that Citrix throws an error after step 5 completes - it is known that the Delphi DLL finishes its work with DriverOpen successfully (through logging). As indicated above, this problem happens only on some machines, so I'm wondering whether there's something I might be able to look for that is a "gotcha" that might be causing the problem? Sadly, Citrix's diagnostics (or lack thereof) are particularly woeful - there are no clues given as to what the issue might be, other than a cryptic error message: Error 1021: Invalid Handle That has no help for it. Keep in mind that this process all works on most machines; all are Windows 10 (same build). I'm hoping to be able to resolve this without having to divulge any source code. Edit: On thinking a bit more, I figure that it might help to show my conversion from C to Delphi of one of the types being passed to DriverOpen. The function itself is declared like this in C int DriverOpen(PVD pVd, PVDOPEN pVdOpen, PUINT16 puiSize) Note that the pVdOpen parameter is not referenced at all within the function in the Delphi DLL, however I figure if I might have that wrong, it might be causing some problem. The pVd parameter is used in all functions. These are the relevant types in their C versions and what I've translated them to in Delphi: C #define MODULE_LENGTH 13 #define PWFCAPI TYPEDEF_CDECL TYPEDEF_FAR * typedef UINT32 (PWFCAPI PLIBPROCEDURE)(); typedef PVOID HND; typedef struct _DLLLINK { /* NOTE: 1st six elements must be same as MINIDLL */ USHORT Segment; /* starting seg of mem allocated for dll (aligned) */ USHORT DllSize; /* actual size of dll in paragraphs */ USHORT ProcCount; /* number of procedures in call table */ PVOID pProcedures; /* pointer to procedure call table */ PVOID pData; /* pointer to dll data structure */ PUCHAR pMemory; /* pointer to malloced memory (not aligned) */ BYTE ModuleName[MODULE_LENGTH]; /* client module name (8.3) */ LPVOID pLibMgrCallTable; /* Pointer to LibMgrTable (input) */ USHORT ModuleDate; /* module date in dos format */ USHORT ModuleTime; /* module time in dos format */ ULONG ModuleSize; /* module file size in bytes */ struct _DLLLINK * pNext; /* pointer to next DLLLINK structure */ ULONG DllFlags; /* DLL flags (embed..) */ /* Everything after here is not included for the ModuleEnum call. */ HND LibraryHandle; } DLLLINK, * PDLLLINK; typedef struct _VDOPEN { LPVOID pIniSection; PDLLLINK pWdLink; ULONG ChannelMask; PLIBPROCEDURE pfnWFEngPoll; PLIBPROCEDURE pfnStatusMsgProc; HND hICAEng; } VDOPEN, FAR * PVDOPEN; Delphi: HND = THandle; PLIBPROCEDURE = function: UINT32; cdecl; PDLLLINK = ^DLLLINK; _DLLLINK = record Segment: USHORT; DllSize: USHORT; ProcCount: USHORT; pProcedures: Pointer; pData: Pointer; pMemory: PUCHAR; ModuleName: array[0..12] of Byte; pLibMgrCallTable: ^DWORD; ModuleDate: USHORT; ModuleTime: USHORT; ModuleSize: ULONG; pNext: PDLLLINK; DllFlags: ULONG; LibraryHandle: HND end; DLLLINK = _DLLLINK; PVDOPEN = ^VDOPEN; __VDOPEN = record pIniSection: Pointer; pWdLink: PDLLLINK; ChannelMask: ULONG; pfnWFEngPoll: PLIBPROCEDURE; pfnStatusMsgProc: PLIBPROCEDURE; hICAEng: HND end; VDOPEN = __VDOPEN;
  22. Dave Nottage

    "Gotchas" when calling from a C DLL to a Delphi DLL?

    What else might it be doing, if the call to the Delphi DLL does not return "properly"?
  23. Dave Nottage

    "Gotchas" when calling from a C DLL to a Delphi DLL?

    Thanks for the other tips. For this one, I still don't know whether or not I have coded the exception handler correctly, or is it just the IntToStr thing that's a problem?
  24. Dave Nottage

    "Gotchas" when calling from a C DLL to a Delphi DLL?

    What is the correct way? Unfortunately, that is easier said than done. The process which loads the DLL runs only when an app is run on Citrix, and it makes the calls to DriverOpen etc immediately, and once the process fails it needs to be restarted, which makes it nigh on impossible to attach to the process that is loading the DLL, let alone debug it. For the first point: I'll need to double check that tomorrow, however given that everything works 100% of the time on most machines, I figure it's unlikely. For the second point: in what ways might this happen? For the third point: That's the reason why I have the exception handler, if I can make it work
  25. Dave Nottage

    "Gotchas" when calling from a C DLL to a Delphi DLL?

    Regarding going down the route of a "pure" Delphi DLL: The DLL needs to link to a .lib file that is provided with the SDK. Since Delphi cannot link to .lib files, I needed to extract the .obj file (there is only one in the .lib) and link to that. There are 9 symbols that need to be linked to: 2 are "direct" static links that look like this: function _Load(pLink: PDLLLINK): Integer; cdecl; external name '_Load'; function VdCallWd(pVd: PVD; ProcIndex: USHORT; pParam: PVOID; puiSize: PUINT16): Integer; stdcall; external name '_VdCallWd@16'; I'm not sure of the correct terminology for it, however the other 7 symbols are the functions that need to be "implemented", including DriverOpen, however because of name mangling, they're exported with symbol names like this (e.g.): _DriverOpen@12. Since it's impossible to name Delphi functions with an "@" symbol, I used ObjConv to rename the symbols, removing the @12 and while I was at it, the underscore. This results in, for example, DriverOpen being declared thus: function DriverOpen(pVd: PVD; pVdOpen: PVDOPEN; puiSize: PUINT16): Integer; stdcall; I cannot add "external" and "name" for these functions because they need to be "implemented", rather than "direct" static links. Again, not sure of the exact terminology for this distinction. In this "pure" Delphi DLL mode, everything compiles OK and Citrix loads the DLL successfully, however for one reason or another it never calls DriverOpen (at all, in this mode), which apparently (as per my original post) it usually calls first. It does however call the DriverInfo function, and does so successfully. Note that the only function that is exported is the Load function (as per their C examples). The Load function is documented as doing the work of setting up a call table to the other functions. Thanks regarding the HND type and pLibMgrCallTable ; I have now corrected that. As far as the "pure" mode goes, this made no difference, however. Back to the "conduit" mode: I had set up some logging to dump what values are coming into the C DLL, and into the Delphi DLL, and see what goes back from Delphi to C, in case there was something untoward happening, and I've discovered that although the DriverOpen function in the Delphi DLL actually completes, it does not return to the calling point in the C DLL, i.e. there's a problem somewhere in between. I put in an exception handler, but I guess it's not right: char* IntToStr(int Number) { char Result[50]; sprintf(Result, "%d", Number); return(Result); } int HandleException(unsigned int code, struct _EXCEPTION_POINTERS *ep) { char Msg[512]; strcpy(Msg, "Exception code : "); strcat(Msg, IntToStr(code)); OutputDebugString(Msg); return EXCEPTION_EXECUTE_HANDLER; } int DriverOpen(PVD pVd, PVDOPEN pVdOpen, PUINT16 puiSize) { OutputDebugString("WSCitrix Conduit DLL DriverOpen called"); if (LoadDelphiDLL()) { __try { int result = DelphiDriverOpen(pVd, pVdOpen, puiSize); OutputDebugString("WSCitrix Conduit DLL DriverOpen returned from Delphi"); return(result); } __except(HandleException(GetExceptionCode(), GetExceptionInformation())) { } } } i.e. it calls DelphiDriverOpen (which completes in the Delphi DLL), but never reaches the subsequent OutputDebugString My limited C skills are probably shining through 😉
×