Announcement

Collapse
No announcement yet.

In-Process COM object DLL template?

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • In-Process COM object DLL template?

    Can anyone provide me with a template for creating an in-process COM object with all the adornments needed to make it a published COM object?

    I have PB9 and I've looked through all the sample code, spent hours reading both the online help and this forum and I'm still unable to put all the pieces together.

    I've been working on a program to control and monitor EPSON data projectors across our campus network (we have hundreds of these projectors.) Creating a "projector" object and giving it methods and properties that reflect what a data projector can do was relatively easy. Implementing the TCP/IP communication code within my projector object was also made easy by PB. In fact it was actually fun! But now I want to move to the next level and publish the projector control COM object so that it can be used by any COM client (PB, VB, VBScript etc.)

    It appears that this step adds a number of syntactic items to the object that are not needed when the object is a simple compiled-in private object.

    The "Create New File" toolbar button in the PB IDE will create a "Generic PB program", "DLL framework using LIBMAIN" etc. But there's no option to generate a framework for a DLL based COM object. Can this be added?

    I had been waiting for PowerBASIC to support some form of OOP and now that it's here I really want to delve into it.

    I hope I've not been to wordy.

    Thanks,
    -Wes
    Last edited by WesWesthaver; 1 Feb 2009, 10:40 PM.

  • #2
    To make a CLASS public:

    1- Make sure you have given the CLASS and each contained interface a GUID to specifically identify it.
    2- Add the words "AS COM" to the end of the CLASS statement.
    3- You now have a COM component.

    The client programs which use this component will probably need a Type Library to get the definitions of your class, so create one with #COM TLIB ON. You mey want to embed the Type Library in the DLL using PBTYP.EXE. You'll probably need to register the COM component on each client computer that uses it. That's done with REGSVR32.EXE.

    Best regards,

    Bob Zale
    PowerBASIC Inc.

    Comment


    • #3
      Thanks Bob,

      What about DispID's, aren't they required for a published COM object? If so, is there a standard way of assigning DispID's? ie: Do they have to be sequential? Are there accepted numeric ranges that you should use? When you have a property get/set pair, do they share the same DispID's? Or do they each need a a unique DispID?

      Also, is this metastatement required?:

      #COM GUID GUID$("{20000000-2000-2000-2000000000000002}")

      The documentation describes it but doesn't indicate when or why it should be used. Is this needed in a published COM component?

      There are so many details described in the help and elsewhere concerning the creation of COM objects that I'm just looking for a working framework to disect and understand.

      The documentation seems to describe each item in question but I can't find any examples that pull all of the details together.

      -Wes

      PS. Am I correct in thinking that I need to use INHERIT IDISPATCH to make it compatible with the widest range of COM clients?
      Last edited by WesWesthaver; 2 Feb 2009, 11:55 AM.

      Comment


      • #4
        Here is a link to a COM dll server and client I posted couple months ago that might be useful. Its just a fancied up version of what's in the PB help relating to Events. Its the fifth post down, I believe.

        http://www.powerbasic.com/support/pb...ad.php?t=39266

        You need to register the server with RegSvr32.

        Get/Set Methods use the same DispID. You can use any numbers you like but starting from 1 makes sense. Details are in the help under the 'Method' heading.

        If your COM object inherits from IDispatch, then so called VTable challenged clients such as VBScript, Java Script, etc., will be able to use it. If your potential clients are regular programming languages such as Visual Basic, C++, etc., they can use either IDispatch or IUnknown direct VTable calls.
        Fred
        "fharris"+Chr$(64)+"evenlink"+Chr$(46)+"com"

        Comment


        • #5
          simple example

          As Mr. Zale has said repeatedly, its incredibly easy to create COM server Dlls with the new PowerBASIC 9.0. I have to admit, I haven't done much of it yet with PB, but I just threw this together quick since my last reply above. Here is a whiz bang COM Dll Server for PB Win 90. I'm gonna see if I can sell this so I can retire early...

          Code:
          #Compile Dll   "MathServer.dll"
          #Com Doc "This Library Helps You Add, Subtract, Multiply & Divide"
          #Com Name "Mathematics", 1.0
          #Com Guid Guid$("{30000098-0000-0000-0000-000000000001}")
          $CLSID_Mathematics = GUID$("{30000098-0000-0000-0000-000000000001}")
          $IID_IMath         = GUID$("{30000098-0000-0000-0000-000000000002}")
                                                                                 
          Class Mathematics $CLSID_Mathematics As Com
            Interface IMath $IID_IMath : Inherit IDispatch
              Method Add       <1> (dblNum1 As Double, dblNum2 As Double) As Double
                Method=dblNum1+dblNum2
              End Method
              Method Subtract  <2> (dblNum1 As Double, dblNum2 As Double) As Double
                Method=dblNum1-dblNum2
              End Method
              Method Multiply  <3> (dblNum1 As Double, dblNum2 As Double) As Double
                Method=dblNum1*dblNum2
              End Method
              Method Divide    <4> (dblNum1 As Double, dblNum2 As Double) As Double
                Method=dblNum1/dblNum2
              End Method                  '
            End Interface
          End Class
          Not only does it add and subtract, but it multiplies and divides too! After you compile it you'll find a MathServer.dll and MathServer.tlb in your working directory.

          To register it execute...

          RegSvr32 "C:\ your path \MathServer.dll"

          To create the type lib open the COM Browser click the 'Open' button and navigate to the tlb file.

          Here is a Console Compiler client that calls the lib making direct VTable calls...

          Code:
          #Compile Exe     "DirectMathClient.exe"
          $CLSID_Mathematics = GUID$("{30000098-0000-0000-0000-000000000001}")
          $IID_IMath         = GUID$("{30000098-0000-0000-0000-000000000002}")
          
          
          Interface IMath $IID_IMath : Inherit IDispatch
            Method Add       <1> (dblNum1 As Double, dblNum2 As Double) As Double
            Method Subtract  <2> (dblNum1 As Double, dblNum2 As Double) As Double
            Method Multiply  <3> (dblNum1 As Double, dblNum2 As Double) As Double
            Method Divide    <4> (dblNum1 As Double, dblNum2 As Double) As Double
          End Interface
          
          
          Function PBMain() As Long
            Dim oMath As IMath
          
            Let oMath=Newcom "Mathematics"
            Print "oMath.Add(8.0,2.0)         = " oMath.Add(8.0,2.0)
            Print "oMath.Subtract(8.0,2.0)    = " oMath.Subtract(8.0,2.0)
            Print "oMath.Multiply(8.0,2.0)    = " oMath.Multiply(8.0,2.0)
            Print "oMath.Divide(8.0,2.0)      = " oMath.Divide(8.0,2.0)
            Set oMath=Nothing
            Waitkey$
          
            PBMain=0
          End Function
          
          'Output
          '=================================
          'oMath.Add(8.0,2.0)         =  10
          'oMath.Subtract(8.0,2.0)    =  6
          'oMath.Multiply(8.0,2.0)    =  16
          'oMath.Divide(8.0,2.0)      =  4

          Here is one that uses the Dispatch Interface...

          Code:
          'Dispatch Version
          #Compile Exe  "DispatchMathClient.exe"
          
          Function PBMain() As Long
            Dim vVar1 As Variant,vVar2 As Variant
            Dim dblResult As Double
            Dim oMath As IDispatch
            
            Let oMath=Newcom "Mathematics"
            vVar1=8.0 : vVar2=2.0
            Object Call oMath.Add(vVar1,vVar2) To dblResult
            Print "oMath.Add(8,2)         = " dblResult
            Object Call oMath.Subtract(vVar1,vVar2) To dblResult
            Print "oMath.Subtract(2,3)    = " dblResult
            Object Call oMath.Multiply(vVar1,vVar2) To dblResult
            Print "oMath.Multiply(8,2)    = " dblResult
            Object Call oMath.Divide(vVar1,vVar2) To dblResult
            Print "oMath.Divide(2,3)      = " dblResult
            Set oMath=Nothing
            Waitkey$
          
            PBMain=0
          End Function
          
          'Output
          '=============================
          'oMath.Add(8,2)         =  10
          'oMath.Subtract(2,3)    =  6
          'oMath.Multiply(8,2)    =  16
          'oMath.Divide(2,3)      =  4

          Please someone who is better at this than I take a look at it. But I think its OK. It works for me.
          Fred
          "fharris"+Chr$(64)+"evenlink"+Chr$(46)+"com"

          Comment


          • #6
            VB6 Use

            And here is late binding through IDispatch with VB6...

            Code:
            Private Sub Form_Click()
              Dim oMath As Object
              
              Set oMath = CreateObject("Mathematics")
              Me.Print "oMath.Add(8.0,2.0) = "; oMath.Add(8#, 2#)
              Me.Print "oMath.Subtract(8.0,2.0) = "; oMath.Subtract(8#, 2#)
              Me.Print "oMath.Multiply(8.0,2.0) = "; oMath.Multiply(8#, 2#)
              Me.Print "oMath.Divide(8.0,2.0) = "; oMath.Divide(8#, 2#)
              Set oMath = Nothing
            End Sub
            Fred
            "fharris"+Chr$(64)+"evenlink"+Chr$(46)+"com"

            Comment


            • #7
              Thanks Fred, It really helps to see a small but functional example.

              I agree that it's easy to create a COM server with PB (if you can put all the correct pieces together in the correct sequence )

              I'm still trying to understand what purpose the metastatements serve such as:

              #Com Name "Mathematics", 1.0

              What is the purpose of #COM NAME "Mathematics", when your already have CLASS Mathematics? Is the COM NAME metastatement just a way to access/update the versioning information embedded in the .DLL?

              Again, I'm just trying to sort it all out.

              -Wes

              Comment


              • #8
                #COM NAME specifies the name of the server and the version number.

                A server can have several classes, no just one.

                It is like asking why a book has a title, if there is already a chapter with a title.
                Forum: http://www.jose.it-berater.org/smfforum/index.php

                Comment


                • #9
                  That said, there's no requirement for a name. If not requested, PowerBASIC just uses the name of the DLL.

                  Comment


                  • #10
                    Originally posted by José Roca View Post
                    #COM NAME specifies the name of the server and the version number.

                    A server can have several classes, no just one.

                    It is like asking why a book has a title, if there is already a chapter with a title.
                    But with a book, it is understood that the name describes its content and allows it to be classified for easy retrieval within a library.

                    In this case, it's optional. So what is its purpose? Apparently Windows doesn't need it. So where is it used? If I don't specify it, what do I lose? If I do specify it, what do I gain?

                    -Wes
                    Last edited by WesWesthaver; 2 Feb 2009, 03:41 PM.

                    Comment


                    • #11
                      Hello Fred,
                      Originally posted by Fred Harris View Post
                      And here is late binding through IDispatch with VB6...

                      Code:
                      Private Sub Form_Click()
                        Dim oMath As Object
                       
                        Set oMath = CreateObject("Mathematics")
                        Me.Print "oMath.Add(8.0,2.0) = "; oMath.Add(8#, 2#)
                        Me.Print "oMath.Subtract(8.0,2.0) = "; oMath.Subtract(8#, 2#)
                        Me.Print "oMath.Multiply(8.0,2.0) = "; oMath.Multiply(8#, 2#)
                        Me.Print "oMath.Divide(8.0,2.0) = "; oMath.Divide(8#, 2#)
                        Set oMath = Nothing
                      End Sub
                      I'd like to believe you, but if we take VBS (or Excel, sorry i don't have vb6 here)...:
                      Code:
                      Set oMath = CreateObject("Mathematics")
                      e = 8.0
                      f = 2.0
                      oMath.Add e, f
                      This leads to a crash telling that the method 'Add' does not exists... kinda same error 91 in VBA Excel.
                      On the opposite, I know and at office i'm a VB/VBA/.NET developer and when I develop a COM DLL then VBS, VBA, VB and VBNET are ALL able to call with success my exposed methods developped with VB or VBNET vs this COM DLL compiled under PB9... or may be there is an hidden trick that really make me blind :-/

                      Comment


                      • #12
                        But with a book, it is understood that the name describes its content and allows it to be classified for easy retrieval within a library.

                        In this case, it's optional. So what is its purpose? Apparently Windows doesn't need it. So where is it used? If I don't specify it, what do I lose? If I do specify it, what do I gain?
                        It is optional, but never left blank. As stated by Mr. Zale, "If not requested, PowerBASIC just uses the name of the DLL." If the servers had not a name, the COM browsers will show you a list of available type libraries without any description. With a list of blank names, I wonder how will you be able to select the wanted one.
                        Forum: http://www.jose.it-berater.org/smfforum/index.php

                        Comment


                        • #13
                          One thing is certain. You already have a "template" -- just take another look at my first post in this thread. It's that simple.

                          "What about DispID's, aren't they required for a published COM object?"

                          They are required to exist, but you do not have to supply them. Leave them out, and PowerBASIC will supply them for you.

                          "If so, is there a standard way of assigning DispID's?"

                          Don't duplicate them, or just let PowerBASIC do it for you.

                          "Do they have to be sequential"

                          No.

                          "Are there accepted numeric ranges that you should use?"


                          Integers greater than zero (0).

                          "When you have a property get/set pair, do they share the same DispID's?"

                          Yes

                          "Also, is this metastatement required?:
                          #COM GUID GUID$("{20000000-2000-2000-2000000000000002}")"


                          No

                          "PS. Am I correct in thinking that I need to use INHERIT IDISPATCH to make it compatible with the widest range of COM clients?"

                          That would be a reasonable inference.


                          Best regards,

                          Bob Zale
                          PowerBASIC Inc.

                          Comment

                          Working...
                          X