Announcement

Collapse
No announcement yet.

In-Process COM object DLL template?

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

  • Bob Zale
    replied
    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.

    Leave a comment:


  • José Roca
    replied
    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.

    Leave a comment:


  • Guest's Avatar
    Guest replied
    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 :-/

    Leave a comment:


  • WesWesthaver
    replied
    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.

    Leave a comment:


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

    Leave a comment:


  • José Roca
    replied
    #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.

    Leave a comment:


  • WesWesthaver
    replied
    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

    Leave a comment:


  • Fred Harris
    replied
    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

    Leave a comment:


  • Fred Harris
    replied
    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.

    Leave a comment:


  • Fred Harris
    replied
    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.

    Leave a comment:


  • WesWesthaver
    replied
    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.

    Leave a comment:


  • Bob Zale
    replied
    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.

    Leave a comment:


  • WesWesthaver
    started a topic In-Process COM object DLL template?

    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.
Working...
X