Announcement

Collapse
No announcement yet.

Calling PB COM from VFP

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

  • Calling PB COM from VFP

    I use a PB DLL to provide a function not easily done with Visual Foxpro. I am trying to write a PB COM object to provide the same function. However, the COM object causes an error in VFP when I try to use it. The function in a DLL works fine. Maybe it is because I need to use ASCIIZ strings in the normal DLL for VFP. Perhaps someone can provide me a idea of how to make the function work in a COM object?

    Here is the DLL, which works fine:

    Code:
    #COMPILE DLL "Str_Functions.DLL"
    #REGISTER ALL
    #INCLUDE "WIN32API.INC"
    GLOBAL ghInstance AS DWORD
    
    FUNCTION LIBMAIN (BYVAL hInstance   AS LONG, BYVAL fwdReason   AS LONG, BYVAL lpvReserved AS LONG) AS LONG
             FUNCTION = 1   'success!
     END FUNCTION
     
    FUNCTION Find_String ALIAS "FindString" (MainString AS ASCIIZ, MatchString AS ASCIIZ, BYVAL Start AS LONG, BYVAL OptCase AS LONG) EXPORT AS LONG
          #REGISTER ALL
         l1& = LEN(MainString)
         l2& = LEN(MatchString)
         IF l1& = 0 OR l2& = 0 THEN
             Find_String& = y&
             EXIT FUNCTION
         END IF
    
         IF start > l1& THEN
              Find_String& = y&
              EXIT FUNCTION
         END IF
    
        IF OptCase& = 1 THEN
          Mainstring = LCASE$(MainString)
          MatchString = LCASE$(MatchString)
        END IF
      y& = INSTR(start, MainString, MatchString)
      Find_String& = y&
    END FUNCTION
    Here is the COM object, which does not work.

    Code:
    #COMPILE DLL "STR_FUNCTIONS_COM3.DLL"
    #DIM ALL
    #COM NAME "STRFUNCTIONS",1.1
    #COM GUID GUID$("{15E1E28D-44B1-497D-9793-5CD9F2B58EDC}")
    #COM TLIB ON
    
    $MyClassGUID        =  GUID$("{27E25675-7BC8-4B40-B594-FD315BC3E00A}")
    $MyFirstInterface   =  GUID$("{AB9BD731-6B72-490E-8B2F-9ABA05C617A1}")
    
    CLASS Str_Find $MyClassGUID AS COM
        INTERFACE mStr_Find $MyFirstInterface
            INHERIT IDISPATCH
            METHOD FindStr <1> (STARTNUM AS LONG, MSTRING AS STRING, FSTRING AS STRING, OPTCASE AS LONG) AS LONG
    
                    IF OPTCASE = 1 THEN
                        MSTRING = UCASE$(MSTRING)
                        FSTRING = UCASE$(FSTRING)
                    END IF
                    METHOD = INSTR(STARTNUM, MSTRING, FSTRING)
            END METHOD
        END INTERFACE
    
    END CLASS
    Afer compliling the COM DLL I register it using ResSvr32. I check that it is registered using PBROW.EXE.

    In VFP I use the following commands to use a COM object:

    oStr = CreatObject("Str_Find") && This creates the object and works

    nPos = oStr.FindStr(1, "Find String Main Subject","Subject") && As soon as I type oStr. the COM object / VFP reports an error and VFP closes.

    Any ideas or pointer will be appreciated. We use COm objects with VFP all the time with not problem. We are very happy that PB will not provide us the capability to create COM objects.

    Thanks,

    John

  • #2
    Have you tried inheriting from DUAL ?
    So here we are, this is the end.
    But all that dies, is born again.
    - From The Ashes (In This Moment)

    Comment


    • #3
      IDISPATCH and DUAL are synonyms

      This is happening in the VBA Editor? This problem normally occurs in VB when debugging a pb com object. Create the object and step through it blows up. Run the application, no debugging, and it works okay..

      IMHO this is a bug in PB
      Sr. Software Development Engineer and Sr. Information Security Analyst,
      CEH, Digital Forensic Examiner

      Comment


      • #4
        Did not say it right

        We are very happy that PB will not provide us the capability to create COM objects.
        I did not mean to say the words above. Sometimes my fingers and brain does not work together. I wanted to say we are very happy with Powerbasic and are glad to see COM incorporated.

        I hope we can make it work with VFP. We use VFP because we love how it easily allows us to manage very larges databases without lots of programming time. Lots of database work can be performed from the command line.

        Could this be because how VFP handles strings? For example, we must use ASCIIZ to pass a string to a PB DLL. I have tried many different interface options and cannot make it work.


        The idea of this simple PB COM object is to test functionality with VFP. Does the structure of the PB COM Object seem correct? I do not have VBA or VB to test the COM object to see if it works with other than VFP. Can someone who does have VB test the PB COM object and let me know if it works.

        Thanks,

        John Sullivan

        Comment


        • #5
          Don't let Thomas bother you, John. {smile}

          First, let me say you can use a PowerBASIC COM Object with VFP successfully. Guaranteed. Unfortunately, I know little about VFP personally, but we'll get you the help you need Monday, if it doesn't show up here sooner.

          Have you tried creating the same COM object in VB6? If that works, I could probably see the correct calling conventions for you to use. This will end up being incredibly easy, once you get past this first step.

          Best regards,

          Bob Zale
          PowerBASIC Inc.

          Comment


          • #6
            Reply to Thomas Tierney

            Thomas,

            This happens from the Visual Foxpro Command line.

            To establish the object we use:

            oStr = CreatObject("Str_Find")

            This creates the object in VFP and works. When we tried to use the object, we type:

            nPos = oStr.FindStr(1, "Find String Main Subject","Subject")

            As soon as I type "oStr." (without quotes) the COM object / VFP reports an error and VFP closes. We use COM objects in VFP everyday with no problems. I was hoping to be able to use PB + COM to provide us functions not available in VFP.

            This is our first attempt to use a PB COM object so we want to have some experts validate that we have the COM code correct.

            Thanks for your help.

            John

            Comment


            • #7
              Thank you, Bob

              Hi Bob,

              Thanks for the reply. We do not have VB so we cannot create the COM in VB to test with VFP. Of course, I can create the COM in VFP but that is not a good test. Since this is our first attempt, perhaps the COM code is not correct?

              I sent it over to support a little while ago so maybe next week someone can look at it.

              I was surprised to see your post on Saturday. Thank you.

              John Sullivan

              Comment


              • #8
                Here's a wild guess, John...

                When you type oStr. would you expect vfp to display a list of the Methods available? If so, it has to access the PowerBASIC Type Library, and it may be expecting to see it embedded in the DLL. Did you embed it with the PB utility?

                Bob Zale

                Comment


                • #9
                  I don't have my notes right here so I can't verify this, but some of the lower value DispID's are reserved. I'd try changing the <1> to a higher number like <401> or some such.

                  Bob

                  Comment


                  • #10
                    When you type oStr. would you expect vfp to display a list of the Methods available? If so, it has to access the PowerBASIC Type Library, and it may be expecting to see it embedded in the DLL. Did you embed it with the PB utility?
                    Yes, I would expect to see a list of methods and properties. I will try what you suggest... if I can figure out how.

                    Thanks,

                    John

                    Comment


                    • #11
                      It's easy! From the doc...

                      As mentioned earlier, you can consolidate your distribution files by embedding your Type Library right into your DLL or EXE as a resource. A utility program named PBTYP.EXE is provided for just that purpose. PBTYP.EXE is executed with one or two command line parameters used to specify the files to be used in the embedding process. The syntax is:

                      PBTYP.EXE TargetFile [ResourceFile]

                      The PBTYP.EXE utility requires that you supply two or three files: the Target File (the DLL or EXE which receives the resource), the TypeLib File (the Type Library to be embedded), and optionally a resource file to be used. Since it's assumed that the Target File and the TypeLib file share the same primary name, only the Target file name is needed. If an extension is not supplied, the default of ".DLL" is used. When executed, PBTYP.EXE scans the original resource file (such as ABC.RC), and replaces any references to a Type Library with a reference to the new Type Library.

                      It then compiles it to a resource object file (such as ABC.RES), and then creates a final PowerBASIC version (such as ABC.PBR). Finally, it removes any prior resource from the target file, and replaces it with the newly created resource. It should be noted that RC.EXE and PBRES.EXE must be present in your path for the process to complete.

                      Comment


                      • #12
                        Hi Bob,

                        When I saw your post I tried to embed the Type Lib into the DLL with no success. First, RC.exe, PBtyp.exe and PBres.exe are in the path.

                        I type in PBtype.exe Str_Functions_Com3.dll and the response back is "Resource file not found". I thought I did not need to specify an RC file.

                        I searched the hard drive to see if one was created and none found.

                        John

                        Comment


                        • #13
                          Bob, you are right!

                          If I turn off the VFP Intellisense Manager, the COM works fine. So, it is the embedding of the type library, which is important.

                          As stated before, all the necessary files are in the path, however, PBtyp.exe complains about not finding the resource file. I type

                          PBtyp.exe str_functions_com3.dll

                          This produces a message says "RC file not found"

                          At the CMD line I can type RC.exe /? or PBRES.exe /? or PBtyp /? and the help is displayed. Any ideas?

                          John

                          Comment


                          • #14
                            Just create a one line text file named "str_functions_com3.rc". Enter this line of text:

                            1 typelib str_functions_com.tlb


                            Put it in the same directory.

                            Bob

                            Comment


                            • #15
                              Speaks eloquently to the advanced error-handing techniques employed in VFP, huh?
                              Michael Mattias
                              Tal Systems (retired)
                              Port Washington WI USA
                              [email protected]
                              http://www.talsystems.com

                              Comment


                              • #16
                                Originally posted by Michael Mattias View Post
                                Speaks eloquently to the advanced error-handing techniques employed in VFP, huh?
                                While i've encountered a few terrible drivers it's to soon to say this is a part or whole issue of VFP.
                                You speak to soon imo.

                                If the com stuff is not entirly correct build, you can not blame another tool not to check all possiblities.
                                It's fairly normal imo that it assumes the com interface is ok.
                                Stability is also part of the com 'guidelines'.

                                And by ok i mean the way the com interface was setup.
                                hellobasic

                                Comment


                                • #17
                                  Call me a purist if you will, but no program should just 'end' (GPF or other) when it does not find something it is looking for. It should tell the user it can't find what it needs and proceed from that point.
                                  Michael Mattias
                                  Tal Systems (retired)
                                  Port Washington WI USA
                                  [email protected]
                                  http://www.talsystems.com

                                  Comment


                                  • #18
                                    That's because you live in the old ages?

                                    A 'component' should work properly once released.
                                    If you buy a dll you will not want to test every possible problem which 'may' happen right?

                                    The point is that what he's doing is under construction, blaming it in this stage is way to soon.

                                    After rereading:
                                    >Call me a purist if you will, but no program should just 'end' (GPF or other) when it does not find something it is looking for.
                                    What a nonsense, if your apps can not find a specific dll "or other" *will* happen.
                                    hellobasic

                                    Comment


                                    • #19
                                      >What a nonsense, if your apps can not find a specific dll "or other" *will* happen.

                                      Call me an purist from an "old age" if you must, but ....

                                      I think that's the kind of use Mr. Zale and his team envisioned when they elected to retain and support the "ELSE" clause of BASIC's "IF .. THEN" statement when creating the first PowerBASIC compilers.

                                      MCM
                                      Michael Mattias
                                      Tal Systems (retired)
                                      Port Washington WI USA
                                      [email protected]
                                      http://www.talsystems.com

                                      Comment


                                      • #20
                                        This VFP code works

                                        Jeff Daniels on the PB staff gave me this information:

                                        COM and VFPCOM rules say that all strings passed must be Unicode. If FoxPro is following the COM Rules (and some Microsoft applications and COM Dlls do not not), then this is a Unicode string. Any strings received from FoxPro will have to be converted to ASCII by using ACODE$ and any strings sent to FoxPro should be converted to Unicode (UCODE$) first .
                                        Jeff is exactly right. Thank you, Jeff. The below COM code works fine with VFP. Visual Foxpro certainly is not Powerbasic but does offer us a way to quickly work with data.


                                        Code:
                                        #COMPILE DLL "STR_COM.DLL"
                                        #DIM ALL
                                        #COM NAME "STRFUNCTIONS",1.1
                                        #COM GUID GUID$("{15E1E28D-44B1-497D-9793-5CD9F2B58EDC}")
                                        #COM TLIB ON
                                        
                                        $MyClassGUID        =  GUID$("{27E25675-7BC8-4B40-B594-FD315BC3E00A}")
                                        $MyFirstInterface   =  GUID$("{AB9BD731-6B72-490E-8B2F-9ABA05C617A1}")
                                        
                                        CLASS Str_Find2 $MyClassGUID AS COM
                                            INSTANCE mstring AS STRING
                                            INSTANCE fstring AS STRING
                                            INSTANCE nResults AS LONG
                                            INSTANCE x AS LONG
                                            INTERFACE mStr_Find $MyFirstInterface
                                                INHERIT IDISPATCH
                                                  METHOD FindStr <601> (STARTNUM AS LONG, ms AS STRING, fs AS STRING, OPTCASE AS LONG) AS LONG
                                                         MSTRING = ACODE$(ms)
                                                         FSTRING = ACODE$(fs)
                                                         IF OPTCASE = 1 THEN
                                                            MSTRING = UCASE$(MSTRING)
                                                            FSTRING = UCASE$(FSTRING)
                                                        END IF
                                                        METHOD = INSTR(STARTNUM, MSTRING, FSTRING)
                                                   END METHOD
                                            END INTERFACE
                                         END CLASS

                                        Since VFP is no longer going to be updated by Microsoft, and will be phased out, I wish someone like Bob Zale would purchase and bring into the 64 bit universe. It is a great tool for quckly working with data.

                                        Thanks Bob and Jeff, for your help.

                                        John Sullivan

                                        Comment

                                        Working...
                                        X