Recent

Author Topic: Importing commercial DDL Question  (Read 8255 times)

thehidden

  • Jr. Member
  • **
  • Posts: 76
  • Freelancer
Importing commercial DDL Question
« on: September 30, 2017, 03:36:20 pm »
Hi to all,
I am not realy familar with importing extenal libraries to a source code, so I need some help.

Datastead sales some nice Graphic Libraries for accessing Webcams and IP Cams via Onvif and RTSP.

Problem: They are not made for Lazarus because they don't include the sourcecode.

I have seen on the demo package follwing files:
Delphi: bpl, dcu, dcp - As fas as I have read not usable with lazarus
C++, C Builder, C#, VB.net etc.: a lot of .dll and .h files.

Is there a possibility to access these .dll files from C++, C#, etc. with Lazarus?

I have found only notices that without knowledge about the .dll structure it would be difficult.

Can anybody give me a kick into the right direction about how to do it?  :-[

Thank you in advance.
I am mostly writing software for Image/Video based Process Documentation and Warehouse/Invoicing.
Other Software only if the project is interesting.

molly

  • Hero Member
  • *****
  • Posts: 2330
Re: Importing commercial DDL Question
« Reply #1 on: September 30, 2017, 03:43:39 pm »
As long as the libraries are provided as real .dll files then you can use them using Free Pascal/Lazarus.

In that case you should be looking at the .h files (header files) which exposes the type and function declarations in order to be able to use the libraries.

Usually when there is also support for Delphi then these header files would already been translated into Pascal. Because i do not knot know which libraries we're talking about, i would have no clue if that would be the case or not.

In case the headers are not already translated to Pascal then try a google-search or the support forums of the commercial entity that provided the libraries and see if someone else already did the hard part for you  :) Also a search on these forums might be able to find you something that would be able to help you out.

edit: 2 relevant links, here and here.
« Last Edit: September 30, 2017, 03:52:16 pm by molly »

thehidden

  • Jr. Member
  • **
  • Posts: 76
  • Freelancer
Re: Importing commercial DDL Question
« Reply #2 on: September 30, 2017, 04:00:36 pm »
Thank you for your information.

Datastead has no forum and their policy is not to support Lazarus.

The DLL Files are for the C... Compilers. Not for Delphi/Pascal.

For Delphi he has the .bpl, .dcu and .dcp files.

Any wrapper to use .dll files, created for C++, CBuilder, C# and anything else outside Pascal?

I have attached some of the .h files. Any usefull information inside if usable with Lazarus? (Delphi Enterpise becomes to expensive)
I am mostly writing software for Image/Video based Process Documentation and Warehouse/Invoicing.
Other Software only if the project is interesting.

molly

  • Hero Member
  • *****
  • Posts: 2330
Re: Importing commercial DDL Question
« Reply #3 on: September 30, 2017, 04:18:21 pm »
Ah, that's funny. VCL classes that are wrapped for use in C  :)

I have to be honest there, afaik this can't be done without some serious labor involved and even then i'm not 100% sure.

A relevant thread might be here.

In principle a library for use with c is not a problem to use with Free Pascal, but this seems cpp and at least needs to be flattened.

I would perhaps be better to wait for someone more experienced on the subject to have a more precise answer.

PS: did i read correctly that there is also a ocx component ? In that case you might be able to use that.
« Last Edit: September 30, 2017, 04:26:22 pm by molly »

thehidden

  • Jr. Member
  • **
  • Posts: 76
  • Freelancer
Re: Importing commercial DDL Question
« Reply #4 on: September 30, 2017, 09:20:37 pm »
Quote
PS: did i read correctly that there is also a ocx component ? In that case you might be able to use that.
Not for all components. More as a Demo for Visual Basic 6.
I am mostly writing software for Image/Video based Process Documentation and Warehouse/Invoicing.
Other Software only if the project is interesting.

molly

  • Hero Member
  • *****
  • Posts: 2330
Re: Importing commercial DDL Question
« Reply #5 on: September 30, 2017, 09:32:00 pm »
ocx is ocx, no matter what. But... i've read wrongly. It seems just a class wrapper around flat dll calls.

How much time do you wish to spend on this yourself if i show you a small start ? e.g. i'm not a philanthropist with too much time on my hands  :D

Do note though that it will not be a visual component, rather a class that you could use.

thehidden

  • Jr. Member
  • **
  • Posts: 76
  • Freelancer
Re: Importing commercial DDL Question
« Reply #6 on: October 01, 2017, 03:46:49 pm »
Quote
How much time do you wish to spend on this yourself if i show you a small start ? e.g. i'm not a philanthropist with too much time on my hands

I estimate that a sample about how to include a simple .dll, some information about "don't and do" and maybe tips how to include a C dll would be helpfull. I will try to get around with the other .dll and figure out how it can work. It is my very first time to include a external .dll and I have no idea how to start.

Quote
Do note though that it will not be a visual component, rather a class that you could use.
No problem, as long as I can access the .dll and get a image file and other information as result from the .dll.

Personal I prefer samples where I can play and test around to figure out how things are going. Slow way, but more a learning way to to something.

What I would try is to create something like below.
Code: Pascal  [Select][+][-]
  1. // NOT REALY A SOURCE CODE BUT A THEORETICAL EXAMPLE!
  2.  
  3. //declaration for external call
  4. function getimage(source:string,parameters:string,format:string):stream;
  5.  
  6. //use of external call
  7. source := 'logitech xy';
  8. parameters:= '800x600';
  9. format:= `jpeg`;
  10. imagea := getimage(source,parameters,format)
  11.  
  12. source := 'rtsp://127.0.0.1@user=none&password=any&channel=0';
  13. parameters:= NULL;
  14. format:= `jpeg`;
  15. imageb := getimage(source,parameters,format)
  16.  
I need just a kick into the rigth direction for accessing and including dll files.
I am mostly writing software for Image/Video based Process Documentation and Warehouse/Invoicing.
Other Software only if the project is interesting.

Phil

  • Hero Member
  • *****
  • Posts: 2737
Re: Importing commercial DDL Question
« Reply #7 on: October 01, 2017, 03:53:09 pm »
I estimate that a sample about how to include a simple .dll, some information about "don't and do" and maybe tips how to include a C dll would be helpfull. I will try to get around with the other .dll and figure out how it can work. It is my very first time to include a external .dll and I have no idea how to start.

https://macpgmr.github.io/MacXPlatform/PascalDynLibs.html


molly

  • Hero Member
  • *****
  • Posts: 2330
Re: Importing commercial DDL Question
« Reply #8 on: October 01, 2017, 04:16:10 pm »
@thehidden:

Ok, let's start with some basics:
- i used the c include file TVideoGrabber.h
- i stuffed my attempt into a pascal unit named VidGrab

What to do first:
a - Declare the library
b - declare the types
c - 'import' the dll functions
d - declare the call-back functions

A:
Code: Pascal  [Select][+][-]
  1. const
  2.   vidgrablib = 'TVideoGrabber_10.6.2.2.dll';
  3.  

B: (simple 2 examples)
Code: Pascal  [Select][+][-]
  1. type
  2.   TAero=(ae_Default, ae_AutoBestRenderingQuality, ae_ForceOnWhenStartingVideo, ae_ForceOffWhenStartingVideo, ae_ForceOnImmediately, ae_ForceOffImmediately);
  3.   TApplicationPriority=(ap_default, ap_idle, ap_normal, ap_high, ap_realtime);
  4.  
Note that it is usually not a good idea to rewrite c enums as pascal enums. Because pascal is much more strict, it will throw errors when out of range. Usually functions returns a out of range value when not part of the enum (such as using -1 for indicating failure). But in basics you can start out with that.

C:
Again two simple examples:
Code: Pascal  [Select][+][-]
  1.   procedure _About (aVGObject: Pointer); stdcall; external vidgrablib;
  2.   function  _AnalogVideoStandardIndex (aVGObject: Pointer; const aValue: pcwchar): cint; stdcall; external vidgrablib;
  3.  
Note that i'm using c-types here. They can be found inside unit ctypes. This makes things easier for you because you could stick to the original types used in c (well, they are sometimes named a bit differently).

To complement this, i added my own types for easy conversion of the c-header:
Code: Pascal  [Select][+][-]
  1. type
  2. type
  3.   cwchar   = WideChar;
  4.   pcwchar  = ^cwchar;
  5.   ppcwchar = ^pcwchar;
  6.  

D:
Some functions inside the library allow you to install a call-back function, and we need to declare them:

Again a couple of simple examples:
Code: Pascal  [Select][+][-]
  1.   TOnAudioDeviceSelectedCb              = procedure(aObject: pointer; aSender: pointer); stdcall;
  2.   TOnAudioPeakCb                        = procedure(aObject: pointer; aSender: pointer; Left_Percent: cdouble; Left_DB: cdouble; Right_Percent: cdouble; Right_DB: cdouble); stdcall;
  3.   TOnAuthenticationNeededCb             = procedure(aObject: pointer; aSender: pointer; AuthenticationType: TAuthenticationType; const Realm: pcwchar; const Server: pcwchar; const Username: ppcwchar; const Password: ppcwchar); stdcall;
  4.  

If you do that for every declared type, dll function, and callback function then you would be able to implement a class encapsulating things. This is my simplistic attempt:
Code: Pascal  [Select][+][-]
  1. type
  2.   TVideoGrabberClass = class
  3.    private
  4.     m_VideoGrabber : pointer;
  5.    public
  6.     constructor Create;
  7.     constructor Create(aClassPtr: pointer);
  8.     destructor  Destroy; override;
  9.    public
  10.     procedure About;
  11.     function  AnalogVideoStandardIndex(aValue: pcwchar): cint;
  12.     procedure ASFStreaming_GetAuthorizationList;
  13.     function  AVIDuration(aAVIFile: pcwchar; aDuration: pcint64; aFrameCount: pcint64): cbool;
  14.     procedure AVIHeaderInfo(aAVIFile: pcwchar; aHeaderAttribute: THeaderAttribute);
  15.  
  16.     function  OpenPlayer: cbool;
  17.     procedure PausePlayer;
  18.     procedure RunPlayer;
  19.     procedure ClosePlayer;    
  20.     procedure SetDisplay_Embedded(aValue: cbool);
  21.     procedure Display_SetLocation(aWindowLeft: cint; aWindowTop: cint; aWindowWidth: cint; aWindowHeight: cint);
  22.    protected
  23.     function  GetPlayerFileName: pcwchar;
  24.     procedure SetPlayerFileName(aValue: pcwchar);
  25.     function  GetAutoStartPlayer: cbool;
  26.     procedure SetAutoStartPlayer(aValue: cbool);
  27.    public
  28.     property  PlayerFileName: pcwchar read GetPlayerFileName write SetPlayerFileName;
  29.     property  AutoStartPlayer: cbool read GetAutoStartPlayer write SetAutoStartPlayer;
  30.  
  31.    //
  32.    // events
  33.    //
  34.    protected
  35.     procedure SetOnPlayerEndOfStream(OnPlayerEndOfStreamCb: TOnPlayerEndOfStreamCb);
  36.     procedure SetOnLog(OnLogCb: TOnLogCb);
  37.    public  
  38.     property  OnPlayerEndOfStream: TOnPlayerEndOfStreamCb write SetOnPlayerEndOfStream;
  39.     property  OnLog: TOnLogCb write SetOnLog;
  40.   end;
  41.  
  42.  
  43. implementation
  44.  
  45.  
  46. constructor TVideoGrabberClass.Create;
  47. begin
  48.   m_VideoGrabber := _CreateVideoGrabber(Self);
  49. end;
  50.  
  51.  
  52. constructor TVideoGrabberClass.Create(aClassPtr: Pointer);
  53. begin
  54.   inherited Create;
  55.   m_VideoGrabber := _CreateVideoGrabber(aClassPtr);
  56. end;
  57.  
  58.  
  59. destructor TVideoGrabberClass.Destroy;
  60. begin
  61.   _DestroyVideoGrabber(m_VideoGrabber);
  62.   m_VideoGrabber := nil;
  63.   inherited;
  64. end;
  65.  
  66.  
  67. procedure TVideoGrabberClass.About;
  68. begin
  69.   _About(m_VideoGrabber);
  70. end;
  71.  
  72.  
  73. function  TVideoGrabberClass.AnalogVideoStandardIndex(aValue: pcwchar): cint;
  74. begin
  75.   result := _AnalogVideoStandardIndex(m_VideoGrabber, aValue);
  76. end;
  77.  
  78.  
  79. procedure  TVideoGrabberClass.ASFStreaming_GetAuthorizationList;
  80. begin
  81.   _ASFStreaming_GetAuthorizationList(m_VideoGrabber);
  82. end;
  83.  
  84.  
  85. function  TVideoGrabberClass.AVIDuration(aAVIFile: pcwchar; aDuration: pcint64; aFrameCount: pcint64): cbool;
  86. begin
  87.   result := _AVIDuration(m_VideoGrabber, aAVIFile, aDuration, aFrameCount);
  88. end;
  89.  
  90.  
  91. procedure TVideoGrabberClass.AVIHeaderInfo(aAVIFile: pcwchar; aHeaderAttribute: THeaderAttribute);
  92. begin
  93.   _AVIHeaderInfo (m_VideoGrabber, aAVIFile, aHeaderAttribute);
  94. end;
  95.  
  96.  
  97.  
  98. function  TVideoGrabberClass.GetPlayerFileName: pcwchar;
  99. begin
  100.   Result := _GetPlayerFileName(m_VideoGrabber);
  101. end;
  102.  
  103.  
  104. procedure TVideoGrabberClass.SetPlayerFileName(aValue: pcwchar);
  105. begin
  106.   _SetPlayerFileName(m_VideoGrabber, aValue);
  107. end;
  108.  
  109.  
  110. function  TVideoGrabberClass.GetAutoStartPlayer: cbool;
  111. begin
  112.   Result := _GetAutoStartPlayer (m_VideoGrabber);
  113. end;
  114.  
  115.  
  116. procedure TVideoGrabberClass.SetAutoStartPlayer(aValue: cbool);
  117. begin
  118.   _SetAutoStartPlayer (m_VideoGrabber, aValue);
  119. end;
  120.  
  121.  
  122. function  TVideoGrabberClass.OpenPlayer: cbool;
  123. begin
  124.   Result := _OpenPlayer (m_VideoGrabber);
  125. end;
  126.  
  127.  
  128. procedure TVideoGrabberClass.PausePlayer;
  129. begin
  130.   _PausePlayer (m_VideoGrabber);
  131. end;
  132.  
  133. procedure TVideoGrabberClass.RunPlayer;
  134. begin
  135.   _RunPlayer (m_VideoGrabber);
  136. end;
  137.  
  138. procedure TVideoGrabberClass.ClosePlayer;    
  139. begin
  140.   _ClosePlayer (m_VideoGrabber);
  141. end;
  142.  
  143. procedure TVideoGrabberClass.SetOnPlayerEndOfStream(OnPlayerEndOfStreamCb: TOnPlayerEndOfStreamCb);
  144. begin
  145.   _SetOnPlayerEndOfStream (m_VideoGrabber, OnPlayerEndOfStreamCb);
  146. end;
  147.  
  148. procedure TVideoGrabberClass.SetDisplay_Embedded(aValue: cbool);
  149. begin
  150.   _SetDisplayEmbedded (m_VideoGrabber, 0, aValue);
  151. end;
  152.  
  153. procedure TVideoGrabberClass.Display_SetLocation(aWindowLeft: cint; aWindowTop: cint; aWindowWidth: cint; aWindowHeight: cint);
  154. begin
  155.   _Display_SetLocation (m_VideoGrabber, aWindowLeft, aWindowTop, aWindowWidth, aWindowHeight);
  156. end;
  157.  
  158. procedure TVideoGrabberClass.SetOnLog(OnLogCb: TOnLogCb);
  159. begin
  160.   _SetOnLog (m_VideoGrabber, OnLogCb);
  161. end;
  162.  

I'm still trying to figure out how some of the functions of the library work, so f.e. i'm still struggling to play a video-file without crashing too hard  :D

Note that the most interesting read was already linked to here but there are others 'manuals' that can be found online and where some of the more 'hidden' caveats are discussed. Also note that in basics you could do with the link i posted, as there isn't much magic going around.

PS: there are tools out there such as h2pas that claim that they can convert c headers automatically for you, but in my experience nine out of ten times these tools choke on macro's, conditional compilation (if then else pre-processor constructs) or otherwise get thrown off. Meaning that in the end you are wasting much more time correcting the c source then it is actually able to save time for you (but your mileage may vary).

In case you have specific question then please feel free to ask those questions. There isn't a strict set of rules to convert c headers files to Pascal (other then let it compile and obey standard Pascal rules).
« Last Edit: October 01, 2017, 04:35:16 pm by molly »

thehidden

  • Jr. Member
  • **
  • Posts: 76
  • Freelancer
Re: Importing commercial DDL Question
« Reply #9 on: October 01, 2017, 05:08:09 pm »
Thank you to molly and to Phil for all the information.

I will do some lessons and see how much I can do. If I need additional help I will let you know.

Thank you.
I am mostly writing software for Image/Video based Process Documentation and Warehouse/Invoicing.
Other Software only if the project is interesting.

avra

  • Hero Member
  • *****
  • Posts: 2514
    • Additional info
Re: Importing commercial DDL Question
« Reply #10 on: October 01, 2017, 09:36:02 pm »
Datastead sales some nice Graphic Libraries for accessing Webcams and IP Cams via Onvif and RTSP.

Problem: They are not made for Lazarus because they don't include the sourcecode.

I have seen on the demo package follwing files:
Delphi: bpl, dcu, dcp - As fas as I have read not usable with lazarus
C++, C Builder, C#, VB.net etc.: a lot of .dll and .h files.

Is there a possibility to access these .dll files from C++, C#, etc. with Lazarus?

I think you might be on the wrong foot with this.

First, if you want to use Datastead TVideoGrabber SDK this means that you have probably bought the TVideoGrabber SDK. Besides VB/C++/C# dll files and demo it includes "Delphi VCL components (32 and 64 bit), Delphi MainDemo project and other Delphi demo projects". This means that you have Pascal sources and that you do not need to use DLLs and examples from other languages. How much these components are compatible with Lazarus is another topic, but it is Pascal and something to start with. Even just looking at Pascal sources to see how some important function was implemented could be of great help.

Second, you mentioned that you want to access cams via Onvif. I don't know much about it, but if I see well then you can download the latest specs from ONVIF and use their WSDLs to generate classes for calling the ONVIF compliant webservices. Lazarus has WST "Web Services Toolkit" which you can use to generate these classes and use them to communicate with ONVIF web services via pure Pascal code. I would go this way if I were you and completely drop need for TVideoGrabber (unless you need it for more then just accessing ONVIF web services).
https://www.onvif.org/profiles/specifications/

Third, you can spy ONVIF network protocol. Wireshark has disector for ONVIF which can help in such task.
https://wiki.wireshark.org/Contrib

In the end, you can ignore all this and try to just use DLLs as if they are used from VB and others. That's what molly is trying to help you with.
« Last Edit: October 01, 2017, 09:43:45 pm by avra »
ct2laz - Conversion between Lazarus and CodeTyphon
bithelpers - Bit manipulation for standard types
pasettimino - Siemens S7 PLC lib

thehidden

  • Jr. Member
  • **
  • Posts: 76
  • Freelancer
Re: Importing commercial DDL Question
« Reply #11 on: October 01, 2017, 11:56:27 pm »
Quote
This means that you have Pascal sources and that you do not need to use DLLs and examples from other languages. How much these components are compatible with Lazarus is another topic, but it is Pascal and something to start with. Even just looking at Pascal sources to see how some important function was implemented could be of great help.
Sorry, but wrong. They don't give you sources. Only .dll and for Delphi only .bpl, .dcu and .dcp files.

Quote
Second, you mentioned that you want to access cams via Onvif. I don't know much about it, but if I see well then you can download the latest specs from ONVIF and use their WSDLs to generate classes for calling the ONVIF compliant webservices. Lazarus has WST "Web Services Toolkit" which you can use to generate these classes and use them to communicate with ONVIF web services via pure Pascal code. I would go this way if I were you and completely drop need for TVideoGrabber (unless you need it for more then just accessing ONVIF web services).
It is not only ONVIF. It can also work with RSTP, Webcams. It has a motion detection algorithem, a recorder for h.264 and avi files and some more. It is a complete set for nearly everything to record videos, images and to use motion detection.

Quote
In the end, you can ignore all this and try to just use DLLs as if they are used from VB and others. That's what molly is trying to help you with.
If it would be only about ONVIF you would be right, but it is much more as this.
I am mostly writing software for Image/Video based Process Documentation and Warehouse/Invoicing.
Other Software only if the project is interesting.

molly

  • Hero Member
  • *****
  • Posts: 2330
Re: Importing commercial DDL Question
« Reply #12 on: October 02, 2017, 12:28:18 am »
I was expecting something similar as you wrote avra but, I'm afraid that user thehidden seems correct there.

I've downloaded the sdk and had a look at their website. Seems you pay for the 'unlocked' sdk. My results show a continues text overlay on the images/video.

From that user hidden is able to conclude that things work with Free Pascal as expected (for as far i've implemented the functionality. some things are still a bit of a mystery to me as the help based on the Delphi component is not helping there with regards to some details when converting pure c-header).

At user thehidden i would probably suggest to base your work on the pure c-header first, then turn it into your own component, which can be based on the Delphi help e.g. mimicking the pure Delphi implementation. But a simple class as defined in the c-header will do just as good if you don't care much about setting properties/events at design time.

Closed source: *barf*
« Last Edit: October 02, 2017, 01:14:46 am by molly »

sam707

  • Guest
Re: Importing commercial DDL Question
« Reply #13 on: October 02, 2017, 02:52:21 am »
just curious...

never heard about "implib" tool on google search and about 'h2pas' on free pascal site ???

I guess h2pas will do 90-99% translation from C header files to pascal units

https://www.freepascal.org/tools/h2pas.var
« Last Edit: October 02, 2017, 02:55:44 am by sam707 »

avra

  • Hero Member
  • *****
  • Posts: 2514
    • Additional info
Re: Importing commercial DDL Question
« Reply #14 on: October 02, 2017, 10:07:34 am »
Quote
This means that you have Pascal sources and that you do not need to use DLLs and examples from other languages. How much these components are compatible with Lazarus is another topic, but it is Pascal and something to start with. Even just looking at Pascal sources to see how some important function was implemented could be of great help.
Sorry, but wrong. They don't give you sources. Only .dll and for Delphi only .bpl, .dcu and .dcp files.
Well, they used to sell the version with sources. Sorry I misslead you, but I was talking from my memory. You can see it here:
http://web.archive.org/web/20130508193113/http://www.datastead.com/purchase.html

Anyway, I see that they include ActiveX and VB6 project in their current SDK:
Quote
ActiveX component for Visual Basic 6.0 (32 bit)
VB6 MainDemo project (designed for vidgrab_VB6.ocx)
So I have downloaded http://www.datastead.com/_releases/vidgrab_10.6.2.2_VB6.zip, registered DLL to Windows and imported ActiveX to Lazarus (Tools / Import Type Library / Vidgrab_VB6 library) and decided to make package and visual component. Nice bindings have been generated and I attach them for your convenience.

That was possible because luckily Lazarus can import ActiveX lately thanks to some nice people doing the hard work (tested with trunk version of Lazarus). In case there was no ActiveX support and you just had plain DLL (but with VB6 bindings), I always had much easier job using using VB to Delphi convertor to convert VB6 bindings (compared to C headers conversion). If I remember well, it usually took me 10 times less effort using this method. VB convertor produces bindings which are almost 100% usable out of the box, unlike h2pas whose result need a lot of mannual tweaking afterwards. And you can also use it to convert VB6 project. You will not get a Delphi project (which you convert to Lazarus) that will work out of the box, but it will be enough to finish the conversion and quickly get a working project with little effort.
http://www.marcocantu.com/tools/vb2delphi.htm
ct2laz - Conversion between Lazarus and CodeTyphon
bithelpers - Bit manipulation for standard types
pasettimino - Siemens S7 PLC lib

 

TinyPortal © 2005-2018