Recent

Author Topic: [Solved]Using C type Reference parameter in DLL  (Read 4574 times)

nygyurka

  • New member
  • *
  • Posts: 6
[Solved]Using C type Reference parameter in DLL
« on: December 12, 2021, 09:19:17 pm »
Hello!
I'm writing a dll that's supposed to interface with a C++ program. According to this programs documentation the program makes the following call:
Code: Pascal  [Select][+][-]
  1. Syntax
  2. HRESULT Describe (
  3. LPCWSTR lpszRuleSet,
  4. LPWSTR lpszOut,
  5. DWORD& dwSize
  6. );
  7.  
My question is how do i handle the DWORD& parameter if i want to interact with it like a Pascal LongWord?
Thank you in advance!

Here is the rest of the relevant documentation if it's needed:
Code: Pascal  [Select][+][-]
  1. Parameters
  2. lpszRuleSet [in, optional]
  3. A null terminated string containing the name of the RuleSet for which the description should be returned. If this value is null, then the general description for the lookup module is returned.
  4. lpszOut [out]
  5. A pointer to a buffer that receives the output data.
  6. dwSize [in, out]
  7. The size of the lpszOut buffer in wide chars. If the output data is larger than the supplied buffer, upon return, this variable will hold the required size.
  8. Return Value
  9. If the function succeeds, the return value is S_OK (0x00000000L). Otherwise, one of the following errors may be returned:
  10. E_INVALIDARG (0x80070057L)
  11.         In the case of the generic Freedom Scientific Lookup Module, this error is returned if lpszRuleSet is NULL (it is optional in general, but not in this specific case). Also returned if lpszOut is NULL or dwSize is 0.
  12. E_RULESET_NOT_FOUND (0x802A0002L)
  13. The rule set specified by lpszRuleSet is not supported by the lookup module.
  14. E_INSUFFICIENT_BUFFER (0x802A0001L)
  15. lpszName is not large enough to hold the return data.
  16.  
« Last Edit: December 14, 2021, 10:52:24 pm by nygyurka »

marcov

  • Administrator
  • Hero Member
  • *
  • Posts: 9986
  • FPC developer.
Re: Using C type Reference parameter in DLL
« Reply #1 on: December 12, 2021, 09:23:52 pm »
If it allows passing NIL/NULL to dwsize, translate it as a pointer to dword (PDWORD).

If not, you can also translate it as VAR dwsize : dword;

440bx

  • Hero Member
  • *****
  • Posts: 2755
Re: Using C type Reference parameter in DLL
« Reply #2 on: December 12, 2021, 09:29:17 pm »
If it allows passing NIL/NULL to dwsize, translate it as a pointer to dword (PDWORD).

If not, you can also translate it as VAR dwsize : dword;
My knowledge of C++ isn't particularly good but, I believe the ampersand (&) requires a variable (as var does in Pascal).  If that is correct then the equivalent is the second option you mentioned.  Of course, that's leaving out "tricks" used to pass nil as a "var" parameter.
FPC v3.0.4 and Lazarus 1.8.2 on Windows 7 64bit.

nygyurka

  • New member
  • *
  • Posts: 6
Re: Using C type Reference parameter in DLL
« Reply #3 on: December 13, 2021, 12:27:00 am »
Thank you very much!
I have another related question!
how do i detect if the program passed a null pointer?

nygyurka

  • New member
  • *
  • Posts: 6
Re: Using C type Reference parameter in DLL
« Reply #4 on: December 13, 2021, 12:40:14 am »
I'll take a crack at it  8)

Code: Pascal  [Select][+][-]
  1. Function Describe(Const lpSZRulteSet:PWChar; lpSzOut:PWChar; Var dwSize:DWord;):LongInt;
  2. Begin
  3.   If dwSize = 0 Then
  4.       Begin
  5.         dwSize := SizeOfTheActualBufferNeeded;
  6.         Result := OK_CONSTANT;
  7.        Exit;
  8.       End;
  9.    if dwSize < SizeOfTheActualBufferNeeded Then
  10.       begin
  11.         Result := ERROR_CONSTANT;
  12.        Exit;
  13.       Edn;
  14.  ///Otherwise;
  15.  Result := OK_CONSTANT;
  16.  
  17.  dwSize := SizeOfTheActualBUfferNeeded;
  18.   //DO the Code needed to write but to the lpSZOut buffer here;
  19.  

Sorry, Post collision

The function should also be labeled as Stdcall and maybe Export..

Thank you very much! I was trying to do something like this but the program wasn't receiving the data properly and i suspect it's because it passes a null pointer at first hence my second question

nygyurka

  • New member
  • *
  • Posts: 6
Re: Using C type Reference parameter in DLL
« Reply #5 on: December 13, 2021, 12:49:19 am »
Just to be clear i did this:
Code: Pascal  [Select][+][-]
  1. function Describe(const lpszRuleSet: LPCWSTR; lpszOut: LPWSTR; var dwSize: DWord): LongWord; cdecl;
  2. begin
  3.  
  4.      description :='Mukodj pls'; //PWideChar
  5.      if dwSize >21 then
  6.         strCopy(lpszOut,description)
  7.      else
  8.          begin
  9.               dwSize := 21;
  10.               result := $802A0001
  11.          end;
  12.      result := 0;
  13. end;

And according to API Monitor the only thing that changes pre and post-call is:
Code: Pascal  [Select][+][-]
  1. 0000  0000  to 0000  0015 0000
I would assume it is due to incorrect buffer size but i'm pretty stuck.
« Last Edit: December 13, 2021, 12:58:05 am by nygyurka »

nygyurka

  • New member
  • *
  • Posts: 6
Re: Using C type Reference parameter in DLL
« Reply #6 on: December 13, 2021, 01:28:29 am »
Through repeatedly banging my head against a wall i managed to determine what the problem was.
I thought "result := something" worked like "return something" in C++ where it automatically terminates the program there, instead Pascal continues executing the code after result has been assigned. Thank you very much for your help! I probably wouldn't have realized without your example Jamie.  :)

PascalDragon

  • Hero Member
  • *****
  • Posts: 4008
  • Compiler Developer
Re: Using C type Reference parameter in DLL
« Reply #7 on: December 13, 2021, 02:06:30 pm »
how do i detect if the program passed a null pointer?

For a reference parameter one shouldn't be able to pass a NULL in C++, but anyway:

Code: Pascal  [Select][+][-]
  1. function VarTest(var dwSize:DWord):LongInt;
  2. begin
  3.   if not Assigned(@dwSize) then begin
  4.     Writeln('Is Nil');
  5.     Exit(0);
  6.   end;
  7.  
  8.   Writeln('Not Nil');
  9. end;
  10.  
  11. var
  12.   dw: DWord;
  13. begin
  14.   VarTest(dw); // will write Not Nil
  15.   VarTest(PDWord(Nil)^); // will write Is Nil
  16. end.

 

TinyPortal © 2005-2018