Author Topic: Question about COM and class  (Read 919 times)

0 Members and 1 Guest are viewing this topic.

Arnold

  • Hero Member
  • *****
  • Posts: 825
Question about COM and class
« on: July 16, 2018, 11:48:36 PM »
Hi Charles,

there is a problem with examples\COM\DirectDrawClass.o2bas; line 48 shows an error for freq:
parameters mismatch for procedure dd1.getmonitorFrequency
params given: #long@1

OPTIONS:
dd1.getmonitorFrequency() returns sys

If I try: #recordof DirectDraw7 then I will see:
...
getmonitorFrequency 4 60 0   9 AD #@1 sys
...

I do not understand the message regarding OPTIONS. Is something missing?
What is the effect of @@DD1 in line 47?

I also found examples\System\GetMonitorFreq.o2bas and GetMonitorFreq2.o2bas which work correctly. Would this be the simpler/better way to work with Ole32.dll and Ddraw.dll?

Roland

John

  • Hero Member
  • *****
  • Posts: 3599
Re: Question about COM and class
« Reply #1 on: July 17, 2018, 12:00:17 AM »
Hi Roland,

Timely question.

Charles put an effort into COM for the DLLC interpreter interface library. I don't know if he carried the effort into the base distribution or not. I would love to see you, Mike, Charles and myself working together to establish a direct  (low level) COM solution for O2. Script BASIC might be a good way to prototype it as it has a working base already established. (SAPI example)
« Last Edit: July 17, 2018, 12:10:45 AM by John »

Arnold

  • Hero Member
  • *****
  • Posts: 825
Re: Question about COM and class
« Reply #2 on: July 17, 2018, 12:12:58 AM »
Hi John,

I see this as a more general question about function pointers in a class and a way which would be best to retrieve them. There are alternatives in O2 to achieve this, but to collect them in a class would be the most elegant solution.

Roland
« Last Edit: July 17, 2018, 01:59:59 AM by Arnold »

Arnold

  • Hero Member
  • *****
  • Posts: 825
Re: Question about COM and class
« Reply #3 on: July 17, 2018, 12:41:23 AM »
Hi Charles,

I modified in line 23:
  sys GetMonitorFrequency(sys a)

and I now get the correct answer. Would this be the solution?

Roland

Arnold

  • Hero Member
  • *****
  • Posts: 825
Re: Question about COM and class
« Reply #4 on: July 17, 2018, 01:00:13 AM »
I also tried this alternative at the beginning of the code:

extern lib "ole32.dll"
! CoInitialize           '1
! CoUninitialize       '0
end extern

extern lib "Ddraw.dll"
! DirectDrawCreate       '3
end extern

  sys freq
...

and this works too. OxygenBasic is cool!

Charles Pegge

  • Admin Support Member
  • *****
  • Posts: 4096
    • Oxygen Basic
Re: Question about COM and class
« Reply #5 on: July 17, 2018, 01:25:44 AM »
Hi Roland,

Yes, you identified the problem. The method prototypes had untyped params. They should default to sys, but it is good to be specific anyway:

Code: [Select]
  sys CoInitialize lib "Ole32.dll" (sys pvReserved)
  sys CoUninitialize lib "Ole32.dll" ()
  sys DirectDrawCreate lib "Ddraw.dll" (sys lpGUID, lplpDD, pUnkOuter)
  sys freq

extern virtual
class DirectDraw7
  sys QueryInterface(sys a, b)
  sys AddRef()
  sys Release()
  sys Compact()
  sys CreateClipper(sys a, b, c)
  sys CreatePalette(sys a, b, c, d)
  sys CreateSurface(sys a, b, c)
  sys DuplicateSurface(sys a, b)
  sys EnumDisplayModes(sys a, b, c, d)
  sys EnumSurfaces(sys a, b, c, d)
  sys FlipToGDISurface()
  sys GetCaps(sys a, b)
  sys GetDisplayMode(sys a)
  sys GetFourCCCodes(sys a, b)
  sys GetGDISurface(sys a)
  sys GetMonitorFrequency(sys a)
  sys GetScanLine(sys a)
  sys GetVerticalBlankStatus(sys a)
  sys Initialize(sys a)
  sys RestoreDisplayMode()
  sys SetCooperativeLevel(sys a, b)
  sys SetDisplayMode(sys a, b, c, d, e)
  sys WaitForVerticalBlank(sys a, b)
  sys GetAvailableVidMem(sys a, b, c)
  sys GetSurfaceFromDC(sys a, b)
  sys RestoreAllSurfaces()
  sys TestCooperativeLevel()
  sys GetDeviceIdentifier(sys a,b)
  sys StartModeTest(sys a,b,c)
  sys EvaluateMode(sys a,b)
end class
end extern

'#recordof DirectDraw7

 
  CoInitialize 0
 
  DirectDraw7 * DD1
  if not DirectDrawCreate(0, @@DD1, 0)
    DD1.GetMonitorFrequency(@freq)
    print ("Your monitor's current frequency is " freq "Hz.")
    DD1.Release
  else
    print ("Failed to create DirectDraw1 surface. Monitor frequency unknown.")
  end if
 
  CoUninitialize





« Last Edit: July 17, 2018, 01:56:27 AM by Charles Pegge »

Josť Roca

  • Sr. Member
  • ****
  • Posts: 263
Re: Question about COM and class
« Reply #6 on: July 17, 2018, 01:42:31 AM »
@Charles,

If you use sys everywhere, you will have problems when compiled to 64 bit.

Arnold

  • Hero Member
  • *****
  • Posts: 825
Re: Question about COM and class
« Reply #7 on: July 17, 2018, 02:02:58 AM »
Thank you Charles. I assume this is a side effect because '#autodim off' is now the default behaviour of Oxygen? But the code looks much clearer now to me and I think I can distinguish between different types of parameters better. I started a small project which will apply this approach of combining the function pointers.

Charles Pegge

  • Admin Support Member
  • *****
  • Posts: 4096
    • Oxygen Basic
Re: Question about COM and class
« Reply #8 on: July 17, 2018, 02:11:56 AM »
True, Josť.

Passing arrays of ints is a case in point.

I can't remember who provided this example, but it would be useful to look at the original prototypes.




Josť Roca

  • Sr. Member
  • ****
  • Posts: 263
Re: Question about COM and class
« Reply #9 on: July 17, 2018, 02:20:03 AM »
To begin with, the return types for AddRef and Release must be ULONG; the return type for the other methods is HRESULT, that is always a LONG in both 32 and 64 bit. Then there are parameters that are DWORDs. A method such SetDisplayMode, to which you have to pass five DWORDs, isn't going to work if you pass five QUADs.

Even for the GetMonitorFrequency you have to pass a pointer to a DWORD. If you use sys freq to declare the variable, you will be passing a pointer to a QUAD.
« Last Edit: July 17, 2018, 02:27:27 AM by Josť Roca »

Charles Pegge

  • Admin Support Member
  • *****
  • Posts: 4096
    • Oxygen Basic
Re: Question about COM and class
« Reply #10 on: July 17, 2018, 03:11:55 AM »
Because of the way in which the Pentium CPU operates, and the fixed 32/64 bit stack width, all direct integer parameters are generally treated the same.

Mike and I had an interesting discussion about 'bloody headers', and the outcome was the corewin headers which have no prototypes. These headers are directly generated from the windows dlls, and largely rely on the compiler to pass parameters in the correct format, with occasional casting by the programmer. This works very well as long as programmers do their MSDN lookups with diligence and supply the correct UDT types and array blocks.  We are so lazy :)