How to cast from virtual abstract class - visual-c++

Having this class definition
class CefBrowser : public virtual CefBase
How to cast from CefBrwoser * to CefBase * and reverse? assuming that both are not instanciable, they are loaded from C to CPP.

Related

Implementing a COM interface in Python

Background: I'm coding in Python and trying to use the win32 IFileOperation to perform shell file operations. In particular, moving/copying a file or directory to a non-existant location requires you to get a IShellItem (or IShellItem2) item referring to the target directory, but SHCreateItemFromParsingName fails if the target doesn't exist yet. Following advice from these related questions:
Creating directories during a copy using IFileOperation
IFileSystemBindData implementation not fully working
I've handled creating the WIN32_FIND_DATAW structure, created the IBindCtx object via pywin32's pythoncom.CreateBindCtx(). The step I'm stuck on is implementing a IFileSysBindData class in Python.
Here's what I've got so far:
class FileSysBindData:
_public_methods_ = ['SetFindData', 'GetFindData']
_reg_clsid_ = '{01E18D10-4D8B-11d2-855D-006008059367}'
def SetFindData(self, win32_find_data):
self.win32_find_data = win32_find_data
return 0
def GetFindData(self, p_win32_find_data):
p_win32_find_data.contents = self.win32_find_data
return 0
bind_data = FileSysBindData()
ibindctx = pythoncom.CreateBindCtx()
# TODO: set the bind data
ibindctx.RegisterObjectParam('File System Bind Data', bind_data)
The last line gives:
ValueError: argument is not a COM object (got type=FileSysBindData)
So obviously there's more to do to get pywin32 to create this in a COM-compatible way.
But I'm stuck on how to use pywin32 (or another solution) to actually create it as a COM object, so I can pass it to the IBindCtx instance.
I'm not super familiar with COM in general, so reading the docs in pywin32 haven't helped me much. I don't even know if I'm supposed to register my class as a server, or use it as a client somehow.
The difficulty is you have to use two python packages:
comtypes to declare and implement custom COM objects
pywin32 because it has lots of already baked interop types, interfaces, classes, etc.
Here is the code, and you'll see the trick to pass a comtypes's custom COM object to pywin32:
import pythoncom
import ctypes
from comtypes.hresult import *
from comtypes import IUnknown, GUID, COMMETHOD, COMObject, HRESULT
from ctypes.wintypes import *
from ctypes import *
from win32com.shell import shell
from os import fspath
# ripped from
# <python install path>\Lib\site-packages\comtypes\test\test_win32com_interop.py
# We use the PyCom_PyObjectFromIUnknown function in pythoncomxxx.dll to
# convert a comtypes COM pointer into a pythoncom COM pointer.
# This is the C prototype; we must pass 'True' as third argument:
# PyObject *PyCom_PyObjectFromIUnknown(IUnknown *punk, REFIID riid, BOOL bAddRef)
_PyCom_PyObjectFromIUnknown = PyDLL(
pythoncom.__file__).PyCom_PyObjectFromIUnknown
_PyCom_PyObjectFromIUnknown.restype = py_object
_PyCom_PyObjectFromIUnknown.argtypes = (POINTER(IUnknown), c_void_p, BOOL)
def comtypes2pywin(ptr, interface=None):
"""Convert a comtypes pointer 'ptr' into a pythoncom PyI<interface> object.
'interface' specifies the interface we want; it must be a comtypes
interface class. The interface must be implemented by the object and
the interface must be known to pythoncom.
If 'interface' is not specified, comtypes.IUnknown is used.
"""
if interface is None:
interface = IUnknown
return _PyCom_PyObjectFromIUnknown(ptr, byref(interface._iid_), True)
class IFileSystemBindData(IUnknown):
"""The IFileSystemBindData interface
https://learn.microsoft.com/en-us/windows/win32/api/shobjidl_core/nn-shobjidl_core-ifilesystembinddata"""
_iid_ = GUID('{01e18d10-4d8b-11d2-855d-006008059367}')
_methods_ = [
COMMETHOD([], HRESULT, 'SetFindData',
(['in'], POINTER(WIN32_FIND_DATAW), 'pfd')),
COMMETHOD([], HRESULT, 'GetFindData',
(['out'], POINTER(WIN32_FIND_DATAW), 'pfd'))
]
class FileSystemBindData(COMObject):
"""Implements the IFileSystemBindData interface:
https://learn.microsoft.com/en-us/windows/win32/api/shobjidl_core/nn-shobjidl_core-ifilesystembinddata"""
_com_interfaces_ = [IFileSystemBindData]
def IFileSystemBindData_SetFindData(self, this, pfd):
self.pfd = pfd
return S_OK
def IFileSystemBindData_GetFindData(self, this, pfd):
pfd = self.pfd
return S_OK
find_data = WIN32_FIND_DATAW() # from wintypes
bind_data = FileSystemBindData()
# to avoid this long thing, we could declare a shorter helper on
# FileSystemBindData
bind_data.IFileSystemBindData_SetFindData(bind_data, ctypes.byref(find_data))
ctx = pythoncom.CreateBindCtx()
# we need this conversion to avoid
# "ValueError: argument is not a COM object (got type=FileSystemBindData)"
# error from pythoncom
pydata = comtypes2pywin(bind_data)
ctx.RegisterObjectParam('File System Bind Data', pydata)
item = shell.SHCreateItemFromParsingName(
fspath("z:\\blah\\blah"), ctx, shell.IID_IShellItem2)
SIGDN_DESKTOPABSOLUTEPARSING = 0x80028000
print(item.GetDisplayName(SIGDN_DESKTOPABSOLUTEPARSING)) # prints Z:\blah\blah

AutoMapper LLBLGEN entity class error model to entity > -> SD.LLBLGen.Pro.ORMSupportClasses.IPrefetchPath

I use LLBLGEN, I want to map the entity class with the c # class.
Mapper.CreateMap<Model.Location, EntityClasses.LocationEntity>();
Mapper.CreateMap<EntityClasses.LocationEntity, Model.Location>();
EntityClasses.LocationEntity loEntity = LocationEntity.Query.Where(s => s.Id == 1).FirstOrDefault();
Model.Location model = Mapper.Map(loEntity);
model fills no problem. but model map entity object error
LocationEntity locationEntity = Mapper.Map(model);
Missing type map configuration or unsupported mapping.
Mapping types:
Location -> IPrefetchPath
Model.Location -> SD.LLBLGen.Pro.ORMSupportClasses.IPrefetchPath
Destination path:
LocationEntity
Source value:
Model.Location
What is a problem ?

Groovy: re-compile a class from file and memory leaks

As per ref-doc:
A GroovyClassLoader keeps a reference of all the classes it created, so it is easy to create a memory leak. In particular, if you execute the same script twice, if it is a String, then you obtain two distinct classes!
I use a file as a source for parsing but turned caching off:
GroovyCodeSource src = new GroovyCodeSource( file )
src.cachable = false
Class clazz = groovyClassLoader.parseClass src
Class clazz1 = groovyClassLoader.parseClass src
log.info "$clazz <=> $clazz1 equal: ${clazz == clazz1}"
the log output is always
class MyClass <=> class MyClass equal: false
If I comment the line src.cachable = false, then the class instances become equal, but they are NOT re-compiling even though the underlying file has changed.
Hence the question: how can I re-compile classes properly without creating a memory leak?
i did the following test and don't see any memory leak.
as for me, the normal GC work.
the link to your class will be alive while any instance of class is alive.
GroovyCodeSource src = new GroovyCodeSource( 'println "hello world"', 'Test', '/' )
src.cachable = false
def cl=this.getClass().getClassLoader()
for(int i=0;i<1000000;i++){
Class clazz = cl.parseClass src
if(i%10000==0)println "$i :: $clazz :: ${System.identityHashCode(clazz)}"
}
After doing some experiments, I figured out that switching back to using String:
String src = 'class A {}'
Class clazz = groovyClassLoader.parseClass src
log.info groovyClassLoader.loadedClasses.join( ', ' )
the loaded classes do not change in lenght, even if a class has some Closures inside (which appear as classes as well).

Groovy - Calling a method with def parameter fails with 'Illegal class name"

I am hoping to get an explanation as to why the call to this Groovy method works as expected:
def f1(int n) {
return n + 1
}
println f1(1) // -> 2
But, if the parameter is not specifically defined ("def n" instead of "int n"), the method call needs to change:
def f2(def n) {
return n + 1
}
println f2(1) // Exception: Illegal class name
println this.&f2(1) // -> 2
What is happening under the hood to make this necessary?
UPDATED with more info:
This is on Windows with Groovy 2.4.5 JVM 1.8.0_51
The entire script is those 9 lines in a file called 1.groovy - nothing else.
I am running this from the console (cmdr) using "groovy 1.groovy"
The error on line 8 is:
Caught: java.lang.ClassFormatError: Illegal class name "3$f2" in class file 3$f2
java.lang.ClassFormatError: Illegal class name "3$f2" in class file 3$f2
at 3.run(3.groovy:8)
This is related to the name of your Script. When you have a file "1.groovy", Groovy generate a class with the name "1" in the default package, which is not a valid class name.
When you use f2(n) without a type, as this method is "too generic", Groovy try to find a matching method, or a class named f2, or an inner class named f2 : loading an inner class f2 of the class 1 fail, because the name is invalid.

How to import files while loading a groovy class?

I am loading a class and doing some sql select statements, it seems that import groovy.sql.Sql needs to be imported. How can I load some library while loading a class?
My code (works fine if I remove Sql operations)
def fClass = new GroovyClassLoader().parseClass( new File( 'plugin/Pi.groovy' ) )
result=fClass.newInstance().buildTags( params, i9piparams, "userRoleCount")
pi.groovy
public class Pi{
def result
private def getDbUrl(dbdriver,dbhost,dbport,dbname)
{
return "$dbdriver:#$dbhost:$dbport:$dbname"
}
public def buildTags(Map<String,String> params,Map<String,String> i9piparams,def i9piType)
{
println params
println i9piparams
/*some Sql operation*/
Driver="oracle.jdbc.driver.OracleDriver"
dbdriver="jdbc:oracle:thin"
def url=getDbUrl(dbdriver,params.tns,i9piparams.dbport,i9piparams.dbname)
def sql = Sql.newInstance(url,params.u,params.x,Driver)
sql.eachRow("select name, value from v\$parameter where name = 'open_cursors'"){ row ->
result.name=row.name
result.value=row.value
}
}
}
Output
[pd:admin, u:zx5531d, tns:foner, dh:abds, dn:D35531, dp:11531, un:admin, x:cx15531]
[:, dbname:orcl, dbport:1521, dbtype:oracle]
Exception in thread "main" groovy.lang.GroovyRuntimeException: Could not find matching constructor for: groovy.sql.Sql(org.codehaus.groovy.runtime.GStringImpl, groovy.util.slurpersupport.Attributes, java.lang.String, java.lang.String)
.
.
.
Can you try changing your line:
def sql = Sql.newInstance(url,params.u,params.x,Driver)
to
def sql = Sql.newInstance( url, 'zx5531d', params.x, Driver )
What I suspect is that you need to call text() on the attributes when you read them from the XML, so that you get a String rather than a groovy.util.slurpersupport.Attributes class.
Also, why has Driver got a capital initial letter?
And (not sure what parameter is), but you probably want to change:
"select name, value from v\$parameter where name = 'open_cursors'"
to
"select name, value from v\${Sql.expand(parameter)} where name = 'open_cursors'"

Resources