Recent

Author Topic: OLE and Widestring  (Read 366 times)

dseligo

  • New Member
  • *
  • Posts: 20
OLE and Widestring
« on: November 21, 2020, 05:06:43 pm »
I have a question regarding OLE and Widestring type.

I am creating OLE object, then calling some method with parameters, something like that:
Code: Pascal  [Select][+][-]
  1. var ole: OleVariant;
  2.     sParameter:String;
  3. ...
  4. sParameter:='test_string';
  5. ole := CreateOLEObject('...ole object...');
  6. ole.SomeFunction(sParameter);
  7.  

And this doesn't work well.

If instead of variable I use literal string then it works fine:
Code: Pascal  [Select][+][-]
  1. ole.SomeFunction('test_string');

I made it working by declaring widestring variable and use it like this:
Code: Pascal  [Select][+][-]
  1. wsParameter:Widestring;
  2. ...
  3. wsParameter:=sParameter;
  4. ...
  5. ole.Somefunction(wsParameter);
  6.  

My question is: Is there a simpler way to use "String" type variable to call OLE method? I tried casting, without luck:
Code: Pascal  [Select][+][-]
  1. ole.Somefunction(WideString(sParameter));

And here (https://wiki.freepascal.org/Widestring) it says that correct way is to use UTF8ToUTF16 function from LazUTF8, I tried like that and it doesn't work either (I get SIGSEGV exception):
Code: Pascal  [Select][+][-]
  1. ole.Somefunction(UTF8ToUTF16(sParameter));

I have this string variable declared elsewhere, and I use it in multiple places in program so I don't want to declare it as a Widestring in a first place - I need to convert it before calling OLE method.

PascalDragon

  • Hero Member
  • *****
  • Posts: 2429
  • Compiler Developer
Re: OLE and Widestring
« Reply #1 on: November 21, 2020, 09:20:31 pm »
Turns out that most of the problems you have (likely) seen where due to a buggy implementation of the parameter dispatching. I have now fixed this in trunk (revisions 47516-47519). If you'd please check whether it works correctly there it would be great and I'd merge that back to 3.2.1 then (so that it will be in the upcoming 3.2.2).

As a workaround (in 3.2.0 and older) you should indeed best use WideString variables.

dseligo

  • New Member
  • *
  • Posts: 20
Re: OLE and Widestring
« Reply #2 on: November 23, 2020, 11:41:53 am »
Thanks for help. It is somewhat better but it isn't solved yet.

I enabled DEBUG_COMDISPATCH in ComObj.pas. This is test program I used:
Code: Pascal  [Select][+][-]
  1. program proba;
  2. uses ComObj, Variants;
  3.  
  4. { $define ws}
  5.  
  6. var ole: OleVariant;
  7.     sPar1,sPar2,sPar3,sPar4,sPar5,sPar6,sPar7:{$ifdef ws}WideString{$else}String{$endif};
  8.  
  9. begin
  10.   sPar1:='FISKAL 4';
  11.   sPar2:='98765432109';
  12.   sPar3:='19.11.2020 09:09:32';
  13.   sPar4:='100';
  14.   sPar5:='P1';
  15.   sPar6:='333';
  16.   sPar7:='99.99';
  17.  
  18.   ole := CreateOLEObject('Raverus.FiskalizacijaDEV.COM.CentralniInformacijskiSustav');
  19.   WriteLn(ole.ZastitniKodIzracun(sPar1,sPar2,sPar3,sPar4,sPar5,sPar6,sPar7));
  20.   VarClear(ole);
  21. end.

This is the output when parameters are WideString:
Code: Pascal  [Select][+][-]
  1. ComObjDispatchInvoke called
  2. ComObjDispatchInvoke: @CallDesc = $0044004C CallDesc^.ArgCount = 7
  3. SearchIDs: Searching 1 IDs
  4. SearchIDs: Original name: ZastitniKodIzracun Len: 18
  5. SearchIDs: Translated name: ZastitniKodIzracun
  6. SearchIDs: GetIDsOfNames result = 00000000
  7. SearchIDs: ID[0] = 1610743821
  8. DispatchInvoke: Got 7 arguments   NamedArgs = 0
  9. DispatchInvoke: Params = 0145FF1C
  10. DispatchInvoke: Got ref argument with type = 8 Value = 99.99
  11. DispatchInvoke: Params = 0145FF20
  12. DispatchInvoke: Got ref argument with type = 8 Value = 333
  13. DispatchInvoke: Params = 0145FF24
  14. DispatchInvoke: Got ref argument with type = 8 Value = P1
  15. DispatchInvoke: Params = 0145FF28
  16. DispatchInvoke: Got ref argument with type = 8 Value = 100
  17. DispatchInvoke: Params = 0145FF2C
  18. DispatchInvoke: Got ref argument with type = 8 Value = 19.11.2020 09:09:32
  19. DispatchInvoke: Params = 0145FF30
  20. DispatchInvoke: Got ref argument with type = 8 Value = 98765432109
  21. DispatchInvoke: Params = 0145FF34
  22. DispatchInvoke: Got ref argument with type = 8 Value = FISKAL 4
  23. DispatchInvoke: MethodID: 1610743821 InvokeKind: 3
  24. f9990122fd1b5fb0abe6bd43b54f94b6

And this is output when parameters are declared as String:
Code: Pascal  [Select][+][-]
  1. ComObjDispatchInvoke called
  2. ComObjDispatchInvoke: @CallDesc = $0044004C CallDesc^.ArgCount = 7
  3. SearchIDs: Searching 1 IDs
  4. SearchIDs: Original name: ZastitniKodIzracun Len: 18
  5. SearchIDs: Translated name: ZastitniKodIzracun
  6. SearchIDs: GetIDsOfNames result = 00000000
  7. SearchIDs: ID[0] = 1610743821
  8. DispatchInvoke: Got 7 arguments   NamedArgs = 0
  9. DispatchInvoke: Params = 0145FF1C
  10. DispatchInvoke: Got argument with type 8 Value = 100
  11. DispatchInvoke: Params = 0145FF20
  12. DispatchInvoke: Got argument with type 8 Value = 100
  13. DispatchInvoke: Params = 0145FF24
  14. DispatchInvoke: Got argument with type 8 Value = 100
  15. DispatchInvoke: Params = 0145FF28
  16. DispatchInvoke: Got argument with type 8 Value = 100
  17. DispatchInvoke: Params = 0145FF2C
  18. DispatchInvoke: Got argument with type 8 Value = ZastitniKodIzracun
  19. DispatchInvoke: Params = 0145FF30
  20. DispatchInvoke: Got argument with type 8 Value = FISKAL 4
  21. DispatchInvoke: Params = 0145FF34
  22. DispatchInvoke: Got argument with type 8 Value = FISKAL 4
  23. DispatchInvoke: MethodID: 1610743821 InvokeKind: 3
  24. 561d46a69e250b902276864552986b40

I couldn't find where "CallDesc" and "Params" are initially set, and I suspect the problem is there.
One more thing. At the beginning of the procedure ComObjDispatchInvoke 3rd parameter was still '19.11.2020 09:09:32', but after call to the SearchIDs procedure it was changed to 'ZastitniKodIzracun'.

I can give you needed dll's if you are willing to further debug this problem.

PascalDragon

  • Hero Member
  • *****
  • Posts: 2429
  • Compiler Developer
Re: OLE and Widestring
« Reply #3 on: November 23, 2020, 11:01:35 pm »
Thanks for help. It is somewhat better but it isn't solved yet.

I enabled DEBUG_COMDISPATCH in ComObj.pas. This is test program I used:

Add {$mode objfpc}{$H+} at the top. By default FPC uses String = ShortString and those indeed don't work. (I've tested your code and I can reproduce your findings only with ShortStrings)

dseligo

  • New Member
  • *
  • Posts: 20
Re: OLE and Widestring
« Reply #4 on: November 24, 2020, 02:40:13 am »
You are right, that was the problem.

These are results with those compiler directives:
Code: Pascal  [Select][+][-]
  1. ComObjDispatchInvoke called
  2. ComObjDispatchInvoke: @CallDesc = $0044004C CallDesc^.ArgCount = 7
  3. SearchIDs: Searching 1 IDs
  4. SearchIDs: Original name: ZastitniKodIzracun Len: 18
  5. SearchIDs: Translated name: ZastitniKodIzracun
  6. SearchIDs: GetIDsOfNames result = 00000000
  7. SearchIDs: ID[0] = 1610743821
  8. DispatchInvoke: Got 7 arguments   NamedArgs = 0
  9. DispatchInvoke: Params = 0145FF1C
  10. Translating var ansistring argument 99.99
  11. DispatchInvoke: Params = 0145FF20
  12. Translating var ansistring argument 333
  13. DispatchInvoke: Params = 0145FF24
  14. Translating var ansistring argument P1
  15. DispatchInvoke: Params = 0145FF28
  16. Translating var ansistring argument 100
  17. DispatchInvoke: Params = 0145FF2C
  18. Translating var ansistring argument 19.11.2020 09:09:32
  19. DispatchInvoke: Params = 0145FF30
  20. Translating var ansistring argument 98765432109
  21. DispatchInvoke: Params = 0145FF34
  22. Translating var ansistring argument FISKAL 4
  23. DispatchInvoke: MethodID: 1610743821 InvokeKind: 3
  24. f9990122fd1b5fb0abe6bd43b54f94b6

PascalDragon

  • Hero Member
  • *****
  • Posts: 2429
  • Compiler Developer
Re: OLE and Widestring
« Reply #5 on: November 24, 2020, 01:36:33 pm »
You are right, that was the problem.

Okay, then I'll make sure that the fixes I've done are merged to 3.2.1 so that they'll be in 3.2.2. :)

 

TinyPortal © 2005-2018