Recent

Author Topic: COM-Client  (Read 1736 times)

kupferstecher

  • Hero Member
  • *****
  • Posts: 583
COM-Client
« on: November 22, 2023, 06:43:23 pm »
Hi,

is it possible to create a COM-Client with Freepascal under Windows? I think it should as Freepascal supports COM-Interfaces, but I didn't find any information on how to connect to a COM-Server. I only found some OLE and ActiveX examples, but I guess thats something else.

See below C++ code snippet, I want to achive the same with freepascal. As far as I understand the #import directive gathers the type information of the COM object, so for a successful compilation the compiler already has to retrieve type information. Is it possible or is there a workaround to gather the type information in other means and to translate it to Pascal 'headers'?

Code: C  [Select][+][-]
  1. #import "libid:BD962F0D-A990-[...]" no_namespace
  2.  
  3.   CoCreateInstance(__uuidof(NNNNDeviceList), [...]
  4.  

Thanks!

Edit: Removed brand name.
« Last Edit: November 24, 2023, 09:39:44 pm by kupferstecher »

marcov

  • Administrator
  • Hero Member
  • *
  • Posts: 11446
  • FPC developer.
Re: COM-Client
« Reply #1 on: November 22, 2023, 07:22:03 pm »
The FPC type importer is called importtl. 

kupferstecher

  • Hero Member
  • *****
  • Posts: 583
Re: COM-Client
« Reply #2 on: November 22, 2023, 09:10:36 pm »
Thanks, I'll have a look! And then perhaps ask further :)

marcov

  • Administrator
  • Hero Member
  • *
  • Posts: 11446
  • FPC developer.
Re: COM-Client
« Reply #3 on: November 22, 2023, 09:52:09 pm »
There are some com related bug reports in the trackers that have good examples.

avra

  • Hero Member
  • *****
  • Posts: 2514
    • Additional info
Re: COM-Client
« Reply #4 on: November 22, 2023, 09:54:54 pm »
is it possible to create a COM-Client with Freepascal under Windows?
Of course it is. OPC DA is based on COM, so you can also take a look at it.
https://sourceforge.net/projects/myopcclient/
https://github.com/seryal/OPCComponent
ct2laz - Conversion between Lazarus and CodeTyphon
bithelpers - Bit manipulation for standard types
pasettimino - Siemens S7 PLC lib

kupferstecher

  • Hero Member
  • *****
  • Posts: 583
Re: COM-Client
« Reply #5 on: November 22, 2023, 11:09:25 pm »
Importtl worked, I used the following command line:
Path\importtl.exe "Path\NNNNCom.exe"
This created a Pascal unit containing all the types and so on, so I can include the unit in the uses of my project. Further questions:

1. I'm not so clear now, how the Com-Server, that I wan't to communicate with, is started. Should it already run when I try to "connect" with the client, or is there an automatic starting mechanism when I instantiate a COM object?

2. What would the CoCreateInstance() (c++) equivalent be in Pascal? I found the CreateComObject() function in avra's link, could it be that?

@avra, thanks for the link, I have a look, but seems to be a bigger project :)

@marcov: Also thanks! About the bug reports, what keywords would you search for, I didn't find anything related so far.

Edit: Removed brand name.
« Last Edit: November 24, 2023, 09:40:42 pm by kupferstecher »

marcov

  • Administrator
  • Hero Member
  • *
  • Posts: 11446
  • FPC developer.
Re: COM-Client
« Reply #6 on: November 22, 2023, 11:13:26 pm »
1.  Afaik the dll should be registered together with the GUID using the regsvr(32) binary. (admin box in modern windows afaik)

Of course there is always 32-bit vs 64-bit to look out for.

2. 
Code: [Select]
   function CreateComObject(const ClassID : TGUID) : IUnknown;
     begin
       OleCheck(CoCreateInstance(ClassID,nil,CLSCTX_INPROC_SERVER or CLSCTX_LOCAL_SERVER,IUnknown,result));
     end;

So basically it is a simple wrapper, olecheck changes COM related return values into exceptions I think.

bugreports: I don't know if this all surived the mantis -> gitlab changesover, but the old bugreports were tagged as "COM". I think servers are harder than clients though.
« Last Edit: November 22, 2023, 11:15:03 pm by marcov »

kupferstecher

  • Hero Member
  • *****
  • Posts: 583
Re: COM-Client
« Reply #7 on: November 22, 2023, 11:27:35 pm »
Ok, great.

1. OK, I make some tests first.
2. Understood!

Thanks so far!

kupferstecher

  • Hero Member
  • *****
  • Posts: 583
Re: COM-Client
« Reply #8 on: November 23, 2023, 09:09:05 pm »
Me, again..

After some tests I'm still stuck with an error, EOleSysError: Class not registered. It occurs in the moment the interface is created (Its the first line of code). Compilation works fine.
Code: Pascal  [Select][+][-]
  1. DeviceList:= CreateComObject(IID_INNNNDeviceList) as INNNNDeviceList;
I wonder if I have to load the library before something within the library is refered to.

The error is the same for 64bit and 32bit (crosscompiled on 64bit Lazarus) applications. Also I tested the c++ example code (snippet in post 1) with Visual Studio and that works. So the automatic loading of the COM server obviously can work. The registry stuff was probably done by the installer of the software and driver package of the device that I want to connect with.
I also tried to compile the c++ example code with gcc, but it doesn't support the syntax #import "libid:... Maybe there is some special compiler magic involved with this command?

Anyone any idea how to get it working under Lazarus? Do I have to load the executable somehow? As far as I understand the server is a exe and not a dll.

Thanks!

Here the code:

Code: Pascal  [Select][+][-]
  1. unit uCOMClient;
  2. {$mode ObjFPC}{$H+}
  3.  
  4. interface
  5.  
  6. uses
  7.   Classes, SysUtils,
  8.   ComObj,
  9.   NNNNCOMLib_1_12_TLB;
  10.  
  11. Procedure GetDevices;
  12.  
  13. var
  14.   DeviceList: INNNNDeviceList;
  15.  
  16. implementation
  17.  
  18. Procedure GetDevices;
  19. begin
  20.  
  21.   DeviceList:= CreateComObject(IID_INNNNDeviceList) as INNNNDeviceList; //EOleSysError
  22.  
  23.   writeln('Available Devices: ',DeviceList.Count);
  24.  
  25.   DeviceList:= nil; //automatically released
  26. end;
  27.  
  28. end.
  29.  

Edit: Removed brand name.
« Last Edit: November 24, 2023, 09:42:14 pm by kupferstecher »

marcov

  • Administrator
  • Hero Member
  • *
  • Posts: 11446
  • FPC developer.
Re: COM-Client
« Reply #9 on: November 23, 2023, 09:59:36 pm »
Afaik coinitialize is done by the comobj unit entry code, so this should simply work.

kupferstecher

  • Hero Member
  • *****
  • Posts: 583
Re: COM-Client
« Reply #10 on: November 23, 2023, 10:05:54 pm »
Could i do that manually for testing?

kupferstecher

  • Hero Member
  • *****
  • Posts: 583
Re: COM-Client
« Reply #11 on: November 23, 2023, 10:22:07 pm »
Or is there any way to see what requests the program is sending to the OS? Then perhaps it would be possible to compare what is different to the c++ program.

kupferstecher

  • Hero Member
  • *****
  • Posts: 583
Re: COM-Client
« Reply #12 on: November 23, 2023, 10:36:23 pm »
It seems to work now!

 :D

I took the wrong GUID, should be CLASS_NNNNDeviceList instead of IID_INNNNDeviceList.

Code: Pascal  [Select][+][-]
  1. DeviceList:= CreateComObject(CLASS_NNNNDeviceList) as INNNNDeviceList;

Edit: Removed brand name.
« Last Edit: November 24, 2023, 09:43:01 pm by kupferstecher »

 

TinyPortal © 2005-2018