Results 1 to 19 of 19

Thread: CreateObject question...

  1. #1

    Thread Starter
    Super Moderator Wokawidget's Avatar
    Join Date
    Nov 2001
    Location
    Headingly Occupation: Classified
    Posts
    9,632

    CreateObject question...

    OK. I have used CreateObject many times in COM+ programming.
    But...I now have a standard EXE that has some classes inside it, no external DLL.
    How do I use CreateObject to create a class??
    VB Code:
    1. Dim objWoof As MyClass
    2.    Set objWoof = CreateObject("MyClass")
    Doesn't work...ActiveX EXE cannot create object error...

    What am I doing wrong?

    Woof

  2. #2
    I'm about to be a PowerPoster! mendhak's Avatar
    Join Date
    Feb 2002
    Location
    Ulaan Baator GooGoo: Frog
    Posts
    38,170
    Set objWoof = New MyClass

    Or am I missing something here?

  3. #3
    I'm about to be a PowerPoster! mendhak's Avatar
    Join Date
    Feb 2002
    Location
    Ulaan Baator GooGoo: Frog
    Posts
    38,170
    Yes, that should work. If I'm not mistaken, the CreateObject function is for registered classes.

  4. #4
    Super Moderator si_the_geek's Avatar
    Join Date
    Jul 2002
    Location
    Bristol, UK
    Posts
    41,974

    Re: CreateObject question...

    shouldn't that be:
    VB Code:
    1. Dim objWoof As MyClass
    2.    Set objWoof = CreateObject("Application.MyClass")


    either that or listen to the frog

  5. #5

    Thread Starter
    Super Moderator Wokawidget's Avatar
    Join Date
    Nov 2001
    Location
    Headingly Occupation: Classified
    Posts
    9,632
    Yes...I want to use the create object:
    VB Code:
    1. Private Sub cmdClickMe_Click()
    2. Dim objNew      As clsCommon
    3. Dim strClass    As String
    4.     Select Case GetSelectedOption
    5.         Case OPT_COMPONENT
    6.             strClass = "clsComponent"
    7.         Case OPT_SERVER
    8.             strClass = "clsServer"
    9.         Case OPT_DBASE
    10.             strClass = "clsDBase"
    11.         Case OPT_NONE
    12.             MsgBox "No option selected", vbInformation
    13.     End Select
    14.     If Not (strClass = vbNullString) Then
    15.         Set objNew = CreateObject(strClass)
    16.         objNew.OptButton = "Fish"
    17.         objNew.AddChanges
    18.         Set objNew = Nothing
    19.     End If
    20. End Sub
    Where clsCommon is IMPLEMENTED in the other classes.
    I can do:
    VB Code:
    1. Dim objNew As clsCommon
    2.    Set objNew = New clsComponent
    U see what I'm trying to do?

    Woof

  6. #6

    Thread Starter
    Super Moderator Wokawidget's Avatar
    Join Date
    Nov 2001
    Location
    Headingly Occupation: Classified
    Posts
    9,632

    Re: Re: CreateObject question...

    Originally posted by si_the_geek
    shouldn't that be:
    VB Code:
    1. Dim objWoof As MyClass
    2.    Set objWoof = CreateObject("Application.MyClass")


    either that or listen to the frog
    Same error
    Doesn't work...Boooooooooo

    I hate to admitt it, but the Frog may be right

  7. #7
    I'm about to be a PowerPoster! mendhak's Avatar
    Join Date
    Feb 2002
    Location
    Ulaan Baator GooGoo: Frog
    Posts
    38,170

    Re: Re: Re: CreateObject question...

    Originally posted by Wokawidget


    I hate to admitt it, but the Frog may be right
    Thanks for the vote of confidence.



    Isn't there a call command function of some sort which can evaluate those 'strings' for you? I'm sure you know what I'm talking about. I don't know the name of the function though.

  8. #8
    Addicted Member JRSofty's Avatar
    Join Date
    Jan 2004
    Location
    Somewhere in Germany
    Posts
    149
    Why don't you declare the variable as an object and then set the object. For example


    VB Code:
    1. Dim MyVar as Object
    2.      Set MyVar = CreateObject("MyClass")
    3.  
    4. 'or even better
    5.  
    6.      Set MyVar = CreateObject("AppName.MyClass")

    I found while doing some Multithreading that if you declare the variable first as an Object and then using CreateObject with the name of the class fully typed out that VB is much happier.

    Now if you are using an External ActiveX DLL then you might try the sattelite approach where you explicitly call one dll with the new and then reset it using the CreateObject function for example:

    VB Code:
    1. Public MyVar as New Application000.CLang
    2.      Set MyVar = CreateObject("Application001.CLang")
    Last edited by JRSofty; Jan 15th, 2004 at 07:08 AM.

  9. #9

    Thread Starter
    Super Moderator Wokawidget's Avatar
    Join Date
    Nov 2001
    Location
    Headingly Occupation: Classified
    Posts
    9,632
    Doesn't work.
    The frog is almost certainly right regarding the CreateObject function.
    There is no need to Dim the varible as an object, unless u are not directly referencing the external DLL in your project.

    All my code and classes are in one standard EXE...that's the problem...however...being being thick and all, I overlooked something:
    VB Code:
    1. Private Sub cmdClickMe_Click()
    2. Dim objNew      As clsCommon
    3.     Select Case GetSelectedOption
    4.         Case OPT_COMPONENT
    5.             Set objNew = New clsComponent
    6.         Case OPT_SERVER
    7.             Set objNew = New clsServer
    8.         Case OPT_DBASE
    9.             Set objNew = New clsDBase
    10.         Case OPT_NONE
    11.             MsgBox "No option selected", vbInformation
    12.     End Select
    13.     If Not (objNew Is Nothing) Then
    14.         objNew.OptButton = txtOption
    15.         objNew.AddChanges
    16.         Set objNew = Nothing
    17.     End If
    18. End Sub

    D'oh!
    Why didn't I think of that before...

    Roooaaaarrrrrr

  10. #10

  11. #11
    I'm about to be a PowerPoster! mendhak's Avatar
    Join Date
    Feb 2002
    Location
    Ulaan Baator GooGoo: Frog
    Posts
    38,170
    Originally posted by Wokawidget
    Doesn't work.
    The frog is almost certainly right regarding the CreateObject function.

    The frog is ALWAYS right. The frog makes all the rules!



    VB Code:
    1. Private Sub cmdClickMe_Click()
    2. Dim objNew      As clsCommon
    3.     Select Case GetSelectedOption
    4.         Case OPT_COMPONENT
    5.             Set objNew = New clsComponent
    6.         Case OPT_SERVER
    7.             Set objNew = New clsServer
    8.         Case OPT_DBASE
    9.             Set objNew = New clsDBase
    10.         Case OPT_NONE
    11.             MsgBox "No option selected", vbInformation
    12.     End Select
    13.     If Not (objNew Is Nothing) Then
    14.         objNew.OptButton = txtOption
    15.         objNew.AddChanges
    16.         Set objNew = Nothing
    17.     End If
    18. End Sub

    D'oh!
    Here's your sign...

  12. #12
    Frenzied Member yrwyddfa's Avatar
    Join Date
    Aug 2001
    Location
    England
    Posts
    1,253
    This is the situation:

    CreateObject uses the COM+ subsystem to create components
    New uses the VB runtime system to create components.

    If you declare a class inside a standard EXE no type library will be generated so COM+ cannot determine how to create the proxy/stub stuff. The class cannot be created using CreateObject; you will certainly need to use 'New' Besides 'New' is always faster.

    However if you create a COM+ DLL (so it's hosted inside COM+- dllhost.exe) you shouldn't use the 'New' method to instantiate classes from the same project (DLL) This is because the VB runtime will instantiate the class, and not COM+; in this scenario you would want COM+ to create the object as this will ensure proper JIT activation, and garbage collection.

    However, if you want to create an object in a different DLL, you can use New because the VB runtime will defer the creation to COM+ (so it's effectively like CreateObject, but faster)

    So, in your scenario, you will need to use New (as you are using Implements shouldn't you be creating seperate components for this anyway?)

    My suggestion is to create your components inside a seperate DLL which gives you the architectural choice of doing what you please. Coding to 'get around' a specific problem (when in fact your initial code is entirely good practice) seems to me to be wrong. Sorry Frog.

    Hope this helps.

  13. #13
    I'm about to be a PowerPoster! mendhak's Avatar
    Join Date
    Feb 2002
    Location
    Ulaan Baator GooGoo: Frog
    Posts
    38,170
    Originally posted by yrwyddfa
    ..to me to be wrong. Sorry Frog.


    Eh?

    I agree with you. What gives?

  14. #14
    Frenzied Member yrwyddfa's Avatar
    Join Date
    Aug 2001
    Location
    England
    Posts
    1,253
    Unless I'm mistaken you're encouraging the use of 'New' to avoid the CreateObject problem.

    Perhaps.

    Then again, maybe not.

  15. #15

    Thread Starter
    Super Moderator Wokawidget's Avatar
    Join Date
    Nov 2001
    Location
    Headingly Occupation: Classified
    Posts
    9,632
    So, I have a DLL, BadgerDLL, running under MTS/COmponent Services. This DLL has 2 classes - Woof and Growl.

    My Client UI app creates an instance of Woof using:
    VB Code:
    1. Dim objSausage As Woof
    2.    Set objSausage = New Woof
    That is correct?

    Now what you are saying is that if my class woof creates an instance of Growl then it SHOULD NOT use the NEW statement, but instead use CreateObject, as in:
    VB Code:
    1. 'In class woof
    2. Dim objSausage As Growl
    3.    Set objSausage = New Growl 'BAD BAD! NO! Bad Badger *SLAP*
    4.    Set objSausage = CreateObject("BadgerDLL.Growl") 'this good yes?
    Am I right here?

    Woka

  16. #16
    Frenzied Member yrwyddfa's Avatar
    Join Date
    Aug 2001
    Location
    England
    Posts
    1,253
    That is correct.

  17. #17

  18. #18
    Frenzied Member yrwyddfa's Avatar
    Join Date
    Aug 2001
    Location
    England
    Posts
    1,253
    It might be helpful if I fully explain what is going on.

    This only applies (I think to COM+)

    All configured components; that is those which are loaded into COM+ actually execute in a process called dllhost.exe - unfortunately most people who have come across this file have come across it with an MSBlast variant.

    So all of your calls to this component (from another COM+ component, or other exe) are cross-process calls - which we all know are expensive and generally bad.

    COM will help this process efficiently - VB will not. The part of COM that helps with the object activation (ie creation and destruction) is called the Service Control Manager. What happens is that the SCM will load an instance of your object (after it's first request) so that your object is always loaded inside DLLHOST.exe. COM+ will then manage this instance. If you maintain any form of state across function calls COM will create a new object for you (to maintain that state - but remember you only have 8 threads of execution +n processors so you can only safely have 8 stateful COM object instances at any one time. If you have more the threads are shared in a roundrobin fashion - the axiom here is that any COM component should not maintain any state across function calls - a technique which, infortunately, is alien to most programmers especially C++ ones. This is why most C++ programmers do not have COM on their CV's)

    When you use 'New' or 'CreateObject' VB knows just about enough to make a call to a function called CoCreateInstance which instantiates tells the SCM to create the object (it gets the rest of the relevant information from registry entries) with the following issues . . .

    If you use 'New' and the object that you want to create lives in a seperate DLL then all is fine - the call is sent to the SCM, and COM will manage this on your behalf - properly.

    If you use 'New' and the object that you want to create lives in the same DLL then the VB runtime creates and binds the object on it's own without any help from the SCM. Even worse, the object is never created properly and the COM+ runtime doesn't even know that it exists; so it can never be managed properly. Bear in mind that VB is the ultimate COM component, so operating correctly with the SCM is of utmost importance.

    Hope this helps a little . . .

  19. #19
    Frenzied Member yrwyddfa's Avatar
    Join Date
    Aug 2001
    Location
    England
    Posts
    1,253
    To answer your question: CreateObject is always safe but always slower (it will go to the registry to look up the information) If you know the issues surrounding 'New' you can use your judgement to choose which one to use.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width