Announcement

Collapse
No announcement yet.

Passing interface to function to be created

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

  • #21
    Use the following or PowerBASIC's CALL DWORD syntax.
    Code:
    $IID_ICLRMETAHOST  = GUID$("{D332DB9E-B9B3-4125-8207-A14884F53216}")
    $CLSID_CLRMETAHOST = GUID$("{9280188D-0E8E-4867-B30C-7FA83884E8DE}")
    
      LOCAL classid   AS GUID
      LOCAL riid      AS GUID
      LOCAL hLib      AS DWORD
      LOCAL lpfn      AS DWORD
      LOCAL pMetaHost AS DWORD
      LOCAL hr        AS LONG
    
    'ICLRMetaHost *pMetaHost = NULL;
    'HRESULT hr = CLRCreateInstance(CLSID_CLRMetaHost,
    '                   IID_ICLRMetaHost, (LPVOID*)&PMETAHOST);
    
      hLib = LoadLibrary("mscoree.dll")
      IF hLib THEN
        MSGBOX "found libary"
        lpfn = GetProcAddress(hLib, "CLRCreateInstance")
        IF lpfn THEN
          MSGBOX "found function"
          classid = $CLSID_CLRMETAHOST
          riid    = $IID_ICLRMETAHOST
          ! lea   eax, pMetaHost
          ! push  eax
          ! lea   eax, riid
          ! push  eax
          ! lea   eax, classid
          ! push  eax
          ! call  lpfn
          ! mov   hr, eax
          IF hr = %S_OK THEN
            MSGBOX "It worked!"
          END IF
        END IF
        FreeLibrary hLib
      END IF
    Dominic Mitchell
    Phoenix Visual Designer
    http://www.phnxthunder.com

    Comment


    • #22
      Thanks for the sample

      So now how do you use the pointer pMetehost to get the class so I can use it?

      And after that do I use OBJECT CALL?

      Comment


      • #23
        I think some of my problem is that PB COM Browser is making bad Interfaces
        the one José Roca posted and the one COM Browser generated are different.

        Comment


        • #24
          And after that do I use OBJECT CALL?
          No, the interfaces do not inherit from IDispatch.

          So now how do you use the pointer pMetehost to get the class so I can use it?
          You will need translated headers for metahost.h and mscoree.h.
          In the case of mscoree.h, you can use a type library browser or the mscoree.inc provided by José.
          metahost.h needs to be translated by hand. Unfortunately, José does not appear to have translated it.

          Post some code showing what you are attempting to do after getting the ICLRMetaHost pointer.


          For example, the following is PowerBASIC code, but it does not use PowerBASIC COM syntax.
          Code:
            LOCAL szVersion     AS ASCIIZ * %MAX_PATH
            LOCAL rclsid        AS GUID
            LOCAL riid          AS GUID
            LOCAL hLib          AS DWORD
            LOCAL lpfn          AS DWORD
            LOCAL pMetaHost     AS DWORD
            LOCAL ppRuntime     AS DWORD
            LOCAL pUnk          AS DWORD
            LOCAL lpwsz         AS DWORD
            LOCAL hr            AS LONG
          
            hLib = LoadLibrary("mscoree.dll")
            IF hLib THEN
              lpfn = GetProcAddress(hLib, "CLRCreateInstance")
              IF lpfn THEN
                rclsid  = $CLSID_CLRMETAHOST
                riid    = $IID_ICLRMETAHOST
                ! lea   eax, pMetaHost
                ! push  eax
                ! lea   eax, riid
                ! push  eax
                ! lea   eax, rclsid
                ! push  eax
                ! call  lpfn
                ! mov   hr, eax
                IF hr = %S_OK THEN
                  ' Get a reference for the ICLRRuntimeInfo
                  szVersion = "v4.0.21006" ' 4.0 Beta2
                  lpwsz = CoTaskMemAlloc(1024)
                  IF lpwsz THEN
                    MultiByteToWideChar %CP_ACP, 0, BYVAL VARPTR(szVersion), -1, BYVAL lpwsz, %MAX_PATH
                    riid     = $IID_ICLRRUNTIMEINFO
                    hr = ICLRMetaHost_GetRuntime(pMetaHost, lpwsz, riid, ppRuntime)
                    IF hr = %S_OK THEN
                      ' Load the CLR 
                      rclsid = $CLSID_CLRRUNTIMEHOST
                      riid   = $IID_ICLRRUNTIMEHOST
                      hr = ICLRRuntimeInfo_GetInterface(ppRuntime, rclsid, riid, ppUnk)
                      IF hr = %S_OK THEN
                        ' Start the CLR by using the hosting version 4
                        hr = ICLRRuntimeHost_Start(ppUnk)
                        IF hr = %S_OK THEN
                          ' ... we are off to the races 
                          ' ... we are off to the races 
                        END IF
                        IUnknown_Release ppUnk
                      END IF
                      IUnknown_Release ppRuntime
                    END IF  
                    CoTaskMemFree lpwsz 
                  END IF  
                END IF
              END IF
              FreeLibrary hLib
            END IF
          Dominic Mitchell
          Phoenix Visual Designer
          http://www.phnxthunder.com

          Comment


          • #25
            metahost.h needs to be translated by hand. Unfortunately, José does not appear to have translated it.
            I did a quick translation. See reply #12.
            Forum: http://www.jose.it-berater.org/smfforum/index.php

            Comment


            • #26
              José Roca, so by useing the TypeLib Browser 5.0.0
              if the comment says [retval][out] on the last item, then replace
              ) AS LONG
              with that parameter

              Am I correct in assuming this logic?

              what about those numbered methods MIDL, i see you do not use them, that determines that I don't need to include them in the interface?
              Or is it that those methods don't exist in the Microsoft Docs?

              Comment


              • #27
                José Roca, so by useing the TypeLib Browser 5.0.0
                if the comment says [retval][out] on the last item, then replace
                ) AS LONG
                with that parameter

                Am I correct in assuming this logic?
                That depends if the interface inherits from IUnknown, IAutomation or IDispatch. If it inherits from IUnknown, then it will be a BYREF parameter, and the return value of the method will be an HRESULT (a LONG in 32 bit Windows). If it inherits from IAutomation or IDispatch, then it will be returned as the return value of the METHOD or PROPERTY, and the HRESULT will be accessible calling PB's OBJRESULT function.

                what about those numbered methods MIDL, i see you do not use them, that determines that I don't need to include them in the interface?
                Or is it that those methods don't exist in the Microsoft Docs?
                These are instructions for the MIDL compiler. C++ headers have a lot of stuff that is not needed to work with PB. They have declarations for C++, declarations for C and, sometimes, macros for C, and stub declations for a proxy.
                Forum: http://www.jose.it-berater.org/smfforum/index.php

                Comment


                • #28
                  I am using Powerbasic 10 now and have come up with the following
                  and i have passed through a couple of interfaces, thus it looks like it works
                  but on exit PB/Win IDE 10.00 tells me
                  "Program tried to read or write an invalid memory address"
                  if I run as the exe it takes a while to close.

                  Code:
                  #COMPILE EXE
                  #DIM ALL
                  
                  #INCLUDE "WinBase.inc"
                  
                  $CLSID_CLRMetaHost = GUID$("{9280188D-0E8E-4867-B30C-7FA83884E8DE}")
                  $IID_ICLRDebugging = GUID$("{D28F3C5A-9634-4206-A509-477552EEFB10}")
                  $IID_ICLRDebuggingLibraryProvider = GUID$("{3151C08D-4D09-4F9B-8838-2880BF18FE51}")
                  $IID_ICLRMetaHost = GUID$("{D332DB9E-B9B3-4125-8207-A14884F53216}")
                  $IID_ICLRMetaHostPolicy = GUID$("{E2190695-77B2-492E-8E14-C4B3A7FDD593}")
                  $IID_ICLRProfiling = GUID$("{B349ABE3-B56F-4689-BFCD-76BF39D888EA}")
                  $IID_ICLRRuntimeInfo = GUID$("{BD39D1D2-BA2F-486A-89B0-B4B0CB466891}")
                  $IID_ICLRStrongName = GUID$("{9FD93CCF-3280-4391-B3A9-96E1CDE77C8D}")
                  $IID_IEnumUnknown = GUID$("{00000100-0000-0000-C000-000000000046}")
                  $IID_ISequentialStream = GUID$("{0C733A30-2A1C-11CE-ADE5-00AA0044773D}")
                  $IID_IStream = GUID$("{0000000C-0000-0000-C000-000000000046}")
                  
                  INTERFACE IEnumUnknown $IID_IEnumUnknown
                  
                     INHERIT IUNKNOWN
                  
                     ' =====================================================================================
                     METHOD RemoteNext ( _                                ' VTable offset = 12
                       BYVAL DWORD _                                      ' [in] celt VT_UI4 <Dword>
                     , BYREF IUNKNOWN _                                   ' [out] **rgelt VT_UNKNOWN <IUnknown>
                     , BYREF DWORD _                                      ' [out] *pceltFetched VT_UI4 <Dword>
                     ) AS LONG                                            ' VT_HRESULT <Long>
                     ' =====================================================================================
                     METHOD Skip ( _                                      ' VTable offset = 16
                       BYVAL DWORD _                                      ' [in] celt VT_UI4 <Dword>
                     ) AS LONG                                            ' VT_HRESULT <Long>
                     ' =====================================================================================
                     METHOD RESET ( _                                     ' VTable offset = 20
                     ) AS LONG                                            ' VT_HRESULT <Long>
                     ' =====================================================================================
                     METHOD Clone ( _                                     ' VTable offset = 24
                       BYREF IEnumUnknown _                               ' [out] **ppenum IEnumUnknown <interface>
                     ) AS LONG                                            ' VT_HRESULT <Long>
                     ' =====================================================================================
                  
                  END INTERFACE
                  
                  INTERFACE ICLRRuntimeInfo $IID_ICLRRuntimeInfo
                  
                     INHERIT IUNKNOWN
                  
                     ' =====================================================================================
                     METHOD GetVersionString ( _                          ' VTable offset = 12
                       BYREF WSTRINGZ _                                   ' [out] pwzBuffer VT_LPWSTR
                     , BYREF DWORD _                                      ' [in][out] *pcchBuffer VT_UI4 <Dword>
                     ) AS LONG                                            ' VT_HRESULT <Long>
                     ' =====================================================================================
                     METHOD GetRuntimeDirectory ( _                       ' VTable offset = 16
                       BYREF WSTRINGZ _                                   ' [out] pwzBuffer VT_LPWSTR
                     , BYREF DWORD _                                      ' [in][out] *pcchBuffer VT_UI4 <Dword>
                     ) AS LONG                                            ' VT_HRESULT <Long>
                     ' =====================================================================================
                     METHOD IsLoaded ( _                                  ' VTable offset = 20
                       BYVAL DWORD _                                      ' [in] *hndProcess VT_VOID <Dword>
                     , BYREF LONG _                                       ' [retval][out] *pbLoaded VT_I4 <Long>
                     ) AS LONG                                            ' VT_HRESULT <Long>
                     ' =====================================================================================
                     METHOD LoadErrorString ( _                           ' VTable offset = 24
                       BYVAL DWORD _                                      ' [in] iResourceID VT_UINT <Dword>
                     , BYREF WSTRINGZ _                                   ' [out] pwzBuffer VT_LPWSTR
                     , BYREF DWORD _                                      ' [in][out] *pcchBuffer VT_UI4 <Dword>
                     , BYVAL LONG _                                       ' [in] iLocaleID VT_I4 <Long>
                     ) AS LONG                                            ' VT_HRESULT <Long>
                     ' =====================================================================================
                     METHOD LoadLibrary ( _                               ' VTable offset = 28
                       BYREF WSTRINGZ _                                   ' [in] pwzDllName VT_LPWSTR
                     , BYREF DWORD _                                      ' [retval][out] **phndModule VT_VOID <Dword>
                     ) AS LONG                                            ' VT_HRESULT <Long>
                     ' =====================================================================================
                     METHOD GetProcAddress ( _                            ' VTable offset = 32
                       BYREF ASCIIZ _                                     ' [in] pszProcName VT_LPSTR
                     , BYREF DWORD _                                      ' [retval][out] **ppProc VT_VOID <Dword>
                     ) AS LONG                                            ' VT_HRESULT <Long>
                     ' =====================================================================================
                     METHOD GetInterface ( _                              ' VTable offset = 36
                       BYREF GUID _                                       ' [in] *rclsid GUID <record>
                     , BYREF GUID _                                       ' [in] *riid GUID <record>
                     , BYREF DWORD _                                      ' [retval][out] **ppUnk VT_VOID <Dword>
                     ) AS LONG                                            ' VT_HRESULT <Long>
                     ' =====================================================================================
                     METHOD IsLoadable ( _                                ' VTable offset = 40
                       BYREF LONG _                                       ' [retval][out] *pbLoadable VT_I4 <Long>
                     ) AS LONG                                            ' VT_HRESULT <Long>
                     ' =====================================================================================
                     METHOD SetDefaultStartupFlags ( _                    ' VTable offset = 44
                       BYVAL DWORD _                                      ' [in] dwStartupFlags VT_UI4 <Dword>
                     , BYREF WSTRINGZ _                                   ' [in] pwzHostConfigFile VT_LPWSTR
                     ) AS LONG                                            ' VT_HRESULT <Long>
                     ' =====================================================================================
                     METHOD GetDefaultStartupFlags ( _                    ' VTable offset = 48
                       BYREF DWORD _                                      ' [out] *pdwStartupFlags VT_UI4 <Dword>
                     , BYREF WSTRINGZ _                                   ' [out] pwzHostConfigFile VT_LPWSTR
                     , BYREF DWORD _                                      ' [in][out] *pcchHostConfigFile VT_UI4 <Dword>
                     ) AS LONG                                            ' VT_HRESULT <Long>
                     ' =====================================================================================
                     METHOD BindAsLegacyV2Runtime ( _                     ' VTable offset = 52
                     ) AS LONG                                            ' VT_HRESULT <Long>
                     ' =====================================================================================
                     METHOD IsStarted ( _                                 ' VTable offset = 56
                       BYREF LONG _                                       ' [out] *pbStarted VT_I4 <Long>
                     , BYREF DWORD _                                      ' [out] *pdwStartupFlags VT_UI4 <Dword>
                     ) AS LONG                                            ' VT_HRESULT <Long>
                     ' =====================================================================================
                  
                  END INTERFACE
                  
                  INTERFACE ICLRMetaHost $IID_ICLRMetaHost
                  
                     INHERIT IUNKNOWN
                  
                     ' =====================================================================================
                     METHOD GetRuntime ( _                                ' VTable offset = 12
                       BYREF WSTRINGZ _                                   ' [in] pwzVersion VT_LPWSTR
                     , BYREF GUID _                                       ' [in] *riid GUID <record>
                     , BYREF ICLRRuntimeInfo _                                      ' [retval][out] **ppRuntime VT_VOID <Dword>
                     ) AS LONG                                            ' VT_HRESULT <Long>
                     ' =====================================================================================
                     METHOD GetVersionFromFile ( _                        ' VTable offset = 16
                       BYREF WSTRINGZ _                                   ' [in] pwzFilePath VT_LPWSTR
                     , BYREF WSTRINGZ _                                   ' [out] pwzBuffer VT_LPWSTR
                     , BYREF DWORD _                                      ' [in][out] *pcchBuffer VT_UI4 <Dword>
                     ) AS LONG                                            ' VT_HRESULT <Long>
                     ' =====================================================================================
                     METHOD EnumerateInstalledRuntimes ( _                ' VTable offset = 20
                       BYREF IEnumUnknown _                               ' [retval][out] **ppEnumerator IEnumUnknown <interface>
                     ) AS LONG                                            ' VT_HRESULT <Long>
                     ' =====================================================================================
                     METHOD EnumerateLoadedRuntimes ( _                   ' VTable offset = 24
                       BYVAL DWORD _                                      ' [in] *hndProcess VT_VOID <Dword>
                     , BYREF IEnumUnknown _                               ' [retval][out] **ppEnumerator IEnumUnknown <interface>
                     ) AS LONG                                            ' VT_HRESULT <Long>
                     ' =====================================================================================
                     METHOD MIDL____MIDL_itf_metahost_0000_00000002__ ( _ ' VTable offset = 28
                     ) AS LONG                                            ' VT_HRESULT <Long>
                     ' =====================================================================================
                     METHOD MIDL____MIDL_itf_metahost_0000_00000003__ ( _ ' VTable offset = 32
                     ) AS LONG                                            ' VT_HRESULT <Long>
                     ' =====================================================================================
                     METHOD MIDL____MIDL_itf_metahost_0000_00000004__ ( _ ' VTable offset = 36
                       BYVAL ICLRRuntimeInfo _                            ' *pRuntimeInfo ICLRRuntimeInfo <interface>
                     , BYVAL ICLRMetaHost _                               ' *pfnCallbackThreadSet ICLRMetaHost <interface>
                     , BYVAL ICLRMetaHost _                               ' *pfnCallbackThreadUnset ICLRMetaHost <interface>
                     )                                                    ' VT_VOID
                     ' =====================================================================================
                     METHOD RequestRuntimeLoadedNotification ( _          ' VTable offset = 40
                       BYVAL ICLRMetaHost _                               ' [in] *pCallbackFunction ICLRMetaHost <interface>
                     ) AS LONG                                            ' VT_HRESULT <Long>
                     ' =====================================================================================
                     METHOD QueryLegacyV2RuntimeBinding ( _               ' VTable offset = 44
                       BYREF GUID _                                       ' [in] *riid GUID <record>
                     , BYREF DWORD _                                      ' [retval][out] **ppUnk VT_VOID <Dword>
                     ) AS LONG                                            ' VT_HRESULT <Long>
                     ' =====================================================================================
                     METHOD ExitProcess ( _                               ' VTable offset = 48
                       BYVAL LONG _                                       ' [in] iExitCode VT_INT <Long>
                     ) AS LONG                                            ' VT_HRESULT <Long>
                     ' =====================================================================================
                  
                  END INTERFACE
                  
                  DECLARE FUNCTION CLRCreateInstance (BYREF CLSID AS GUID, BYREF riid AS GUID, BYREF ppInterface AS IUNKNOWN) AS LONG
                  
                  FUNCTION PBMAIN () AS LONG
                      LOCAL hLib AS DWORD
                      LOCAL hCLRCreateInstance AS DWORD
                      LOCAL ret AS DWORD
                      LOCAL dotNetToLoad AS WSTRINGZ * 11
                      dotNetToLoad = "v4.0.30319"
                      hLib = LoadLibrary("mscoree.dll")
                      IF hLib THEN
                          MSGBOX("found library")
                          hCLRCreateInstance = GetProcAddress(hLib, "CLRCreateInstance")
                          IF hCLRCreateInstance THEN
                              MSGBOX("found CLRCreateInstance")
                              LOCAL pCLRMetaHost AS ICLRMetaHost
                              CALL DWORD hCLRCreateInstance USING CLRCreateInstance($CLSID_CLRMetaHost, $IID_ICLRMetaHost, pCLRMetaHost) TO ret
                              IF ret = %S_OK THEN
                                  MSGBOX("I have an instance of CLRMetaHost")
                                  LOCAL pRunTimeInfo AS ICLRRuntimeInfo
                                  ret = pCLRMetaHost.GetRuntime(dotNetToLoad, $IID_ICLRRuntimeInfo, pRunTimeInfo)
                                  IF ret = %S_OK THEN
                                      MSGBOX("Got runtime info")
                                      LOCAL pbLoadable AS DWORD
                                      ret = pRunTimeInfo.IsLoadable(pbLoadable)
                                      IF ret = %S_OK THEN
                                          IF pbLoadable = 1 THEN
                                              MSGBOX("Its loadable")
                                              
                                          END IF
                                      END IF
                                      pRunTimeInfo.Release()
                                  END IF
                                  pCLRMetaHost.Release()
                              END IF
                          END IF
                          FreeLibrary(hLib)
                      END IF
                      FUNCTION = 0
                  END FUNCTION

                  Comment


                  • #29
                    Change

                    Code:
                    hLib = LoadLibrary("mscoree.dll")
                    to

                    Code:
                    ' // See if the library is already loaded in the address space
                    hLib = GetModuleHandle("mscoree.dll")
                    ' // If it is not loaded, load it
                    IF hLib = %NULL THEN hLib = LoadLibrary("mscoree.dll")
                    and remove

                    Code:
                    FreeLibrary(hLib)
                    Otherwise, it will GPF when the application ends and PB will call CoUninitialize under the hood.
                    Last edited by José Roca; 3 Apr 2011, 10:23 PM.
                    Forum: http://www.jose.it-berater.org/smfforum/index.php

                    Comment


                    • #30
                      changed and removed

                      "Program tried to read or write an invalid memory address"

                      on exit still happens
                      it happens as I step past END FUNCTION

                      Comment


                      • #31
                        Maybe you need to do something else, but I don't know. I only have .NET 2 installed.
                        Forum: http://www.jose.it-berater.org/smfforum/index.php

                        Comment


                        • #32
                          It looks like I don't need to call Release() , so I removed them, and no more error.

                          Comment


                          • #33
                            Yes, you don't have to call Release because PB calls it when you set the object variable to NOTHING or it goes out of scope.
                            Forum: http://www.jose.it-berater.org/smfforum/index.php

                            Comment


                            • #34
                              how do I handle methods that have numbers in them?

                              Code:
                                 METHOD CreateInstance <1610743842> ( _               ' VTable offset = 164
                                   BYVAL WSTRING _                                    ' [in] typeName VT_BSTR
                                 ) AS VARIANT                                         ' [retval][out] *pRetVal VT_VARIANT <Variant>

                              Comment


                              • #35
                                In the same way. These numbers are only used by Automation: OBJECT CALL/GET/SET.
                                Forum: http://www.jose.it-berater.org/smfforum/index.php

                                Comment


                                • #36
                                  since I decided to get Dot Net 4 working as a learning exercise (will post up result here when done)
                                  I find myself at Method Load_3 and a VT_SAFEARRAY
                                  Load_3 takes 1 parameter [in] *rawAssembly VT_SAFEARRAY

                                  Not being familiar with a SAFEARRAY and help in PB being no help
                                  How do I give Load_3 a safe array
                                  given that I already have an array AssemblyBytes() AS BYTE filled with the assembly

                                  I tried the following
                                  Code:
                                  LOCAL vAssemblyBytes AS VARIANT
                                  vAssemblyBytes = AssemblyBytes()
                                  LOCAL pv AS VARIANT_NAME_2 PTR
                                  pv = VARPTR( vAssemblyBytes )
                                  pAssembly = pAppDomain.Load_3(@pv.parray)
                                  and that's obviously not it "Access Violation"

                                  Comment


                                  • #37
                                    You must pass a pointer to the safe array, not the address of a variant. To create the safe array, use the safe array API functions or the new PowerArray class.
                                    Forum: http://www.jose.it-berater.org/smfforum/index.php

                                    Comment


                                    • #38
                                      Ok using the PowerArray class, I need some one to show me how once again pb help fails me, as the PowerArray class was the first thing I tried.

                                      Comment


                                      • #39
                                        This creates a safe array of variants.

                                        Code:
                                        DIM psa AS IPowerArray
                                        DIM bounds AS POWERBOUNDS
                                        psa = CLASS "PowerArray"
                                        
                                        bounds.LowBound1  = 1
                                        bounds.Elements1  = 3
                                        psa.Dim(%VT_VARIANT, 1, bounds)
                                        
                                        LOCAL v1, v2, v3 AS VARIANT
                                        v1 = "abc" AS WSTRING
                                        v2 = "def" AS WSTRING
                                        v3 = "ghi" AS WSTRING
                                        
                                        psa.ValueSet(v1, 1)
                                        psa.ValueSet(v2, 2)
                                        psa.ValueSet(v3, 3)
                                        To retrieve the pointer of the safe array descriptor, which is what you have to pass, use psa.ArrayDesc.
                                        Forum: http://www.jose.it-berater.org/smfforum/index.php

                                        Comment


                                        • #40
                                          so do I put one byte in each safearray element?

                                          Comment

                                          Working...
                                          X