How to convert a SAFEARRAY to array of COM pointers - c++

I have a function say foo which returns SAFEARRAY of COM pointers
SAFEARRAY* foo()
{
IMyClassPtr *objs = (IMyClassPtr*)callock(n, sizeof(IMyClassPtr));
CComSafeArray<IDispatch*> sa(n);
for(UINT index = 0; index < n; index++)
{
objs[index].CreateInstance(CLSID_MyClass);
(objs[index])->AddRef();
objs[index]->put_X(index);
objs[index]->put_Y(index+10);
sa.SetAt(index, objs[index]);
}
return sa.Detach();
}
This is my MyClass
class ATL_NO_VTABLE CMyClass :
public CComObjectRootEx<CComSingleThreadModel>,
public CComCoClass<CMyClass, &CLSID_MyClass>,
public IDispatchImpl<IMyClass, &IID_IMyClass, &LIBID_mylibAlias, /*wMajor =*/ 1, /*wMinor =*/ 0>
{
public:
CMyClass();
virtual ~CMyClass();
DECLARE_REGISTRY_RESOURCEID(IDR_MyClass)
BEGIN_COM_MAP(CMyClass)
COM_INTERFACE_ENTRY(IMyClass)
COM_INTERFACE_ENTRY(IDispatch)
END_COM_MAP()
DECLARE_PROTECT_FINAL_CONSTRUCT()
HRESULT FinalConstruct()
{
return S_OK;
}
void FinalRelease()
{
}
protected:
ULONG x;
ULONG y;
public:
STDMETHOD(get_X)(ULONG* pVal);
STDMETHOD(put_X)(ULONG newVal);
STDMETHOD(get_Y)(ULONG* pVal);
STDMETHOD(put_Y)(ULONG newVal);
};
OBJECT_ENTRY_AUTO(__uuidof(MyClass), CMyClass)
now I have done this,
SAFEARRAY* sa;
IMyClassPtr* objs;
sa = foo();
if(SUCCEEDED(SafeArrayAccessData(sa, (void**)&objs)))
{
// At this point, when I debug at the autos window objs contains some value
// and I can see this message also
// <No type information available in symbol file for oleaut32.dll>
}
Please help me fix this issue.

If your safe array contains IDisptach* your call to SafeArrayAccessDate returns an IDispatch**. In fact you get the start of the array of the first pointer.
Also you code to create the objects isn't very useful. You don't need to create the array of objects (and even there is a leak you don't free it again.
Just create one object at a time and assign it to the safe array. There is no need for a second pointer. Also there is a problem with your reference counting. AFAIK there is no need to call AddRef after you createdthe instance. Is is already locked. And you don't want a second lock.
Also you should always use QueryInterface to obtain a pointer of the given type you want to store (IDisptach), and again you need to call QueryInterface when you want to convert the IDispatch back into a IMyClass pointer.

Related

VC++ class objects with a VARIANT member have strange behavior

I have a class defined below:
class CVariable
{
public:
CVariable(CString strData, int nNum);
CVariable(BSTR bsData);
~CVariable();
public:
VARIANT GetVariant(){return m_bsVa;};
private:
VARIANT m_bsVa;
VARIANT m_nVa;
};
And implements are:
CVariable::CVariable(CString strData, int nNum)
{
VariantInit(&m_bsVa);
BSTR bsData = ::SysAllocString(strData);
m_bsVa.vt = VT_BSTR;
m_bsVa.bstrVal = bsData;
::SysFreeString(bsData);
VariantInit(&m_nVa);
m_nVa.vt = VT_I2;
m_nVa.lVal = nNum;
}
CVariable::CVariable(BSTR bsData) {
m_bsVa.vt = VT_BSTR;
m_bsVa.bstrVal = bsData;
}
CVariable::~CVariable()
{
VariantClear(&m_bsVa);
VariantClear(&m_nVa);
}
When I try to construct two instances using constructor CVariable(CString,int),
class member m_bsVas always have the same value,while m_nVas are different.The result is below:
As you see, v1 and v2 have the same m_bsVa but different m_nVa, while using constructor CVariable(BSTR) leads to the right result. I've no idea why this can happen?
Any help will be appreciated.
I see several problems with your code.
the CVariable(CString, int) constructor allocates a BSTR for m_bsVa, but then frees the BSTR immediately, leaving m_bsVa pointing at invalid memory, and allowing the next CVariable instance to potentially reuse the same memory address for its allocated BSTR. You need to leave the BSTR allocated until you are done using m_bsVa (or at least until you want to assign a new value to it). VariantClear() will free the BSTR for you.
the CVariable(BSTR) constructor is not initializing m_nVa at all, which will cause problems for subsequent operations on it, including VariantClear(). Also, the constructor is taking ownership of the caller's BSTR. That may or may not be OK, depending on how you use this constructor. If the caller is not expecting you to take ownership, then you need to make a copy of the BSTR using SysAllocString/Len().
VARIANT is not trivially copyable. You need to use the VariantCopy() function to copy data from one VARIANT to another. That means your CVariable class needs to implement a copy constructor and copy assignment operator. Which you need to do anyway so your class conforms to the Rule of Three.
GetVariant() is returning m_bsVa as-is, so the compiler will simply copy the values of m_bsVa's fields as-is into the caller's receiving VARIANT. Since BSTR is a pointer, the caller will have direct access to the original BSTR inside of your class. That may or may not be OK, depending on how you use GetVariant(). In the current implementation, any access to the returned BSTR should be treated as read-only - the caller must not call SysFreeString() on it, and must expect any change to the CVariable object may invalidate the BSTR. If that does not suit your needs, then GetVariant() should return a new VARIANT that has copied the data via VariantCopy(), and then the caller can call VariantClear() when done using the returned VARIANT.
With that said, try something more like this:
class CVariable
{
public:
CVariable(const CString &strData, int nNum);
CVariable(BSTR bsData);
CVariable(const CVariable &src);
~CVariable();
VARIANT GetVariant() const;
CVariable& operator=(const CVariable &src);
CVariable& operator=(BSTR src);
private:
VARIANT m_bsVa;
VARIANT m_nVa;
};
CVariable::CVariable(const CString &strData, int nNum)
{
::VariantInit(&m_bsVa);
m_bsVa.vt = VT_BSTR;
m_bsVa.bstrVal = ::SysAllocString(strData);
::VariantInit(&m_nVa);
m_nVa.vt = VT_I2;
m_nVa.lVal = nNum;
}
CVariable::CVariable(BSTR bsData)
{
::VariantInit(&m_bsVa);
m_bsVa.vt = VT_BSTR;
m_bsVa.bstrVal = bsData;
/* or this, if needed:
m_bsVa.bstrVal = ::SysAllocStringLen(bsData, ::SysStringLen(bsData));
*/
::VariantInit(&m_nVa);
}
CVariable::~CVariable()
{
::VariantClear(&m_bsVa);
::VariantClear(&m_nVa);
}
VARIANT CVariable::GetVariant() const
{
return m_bsVa;
/* or this, if needed:
VARIANT result;
::VariantInit(&result);
::VariantCopy(&result, &m_bsVa);
return result;
*/
}
CVariable& CVariable::operator=(const CVariable &src)
{
if (&src != this)
{
::VariantClear(&m_bsVa);
::VariantCopy(&m_bsVa, &src.m_bsVa);
::VariantClear(&m_nVa);
::VariantCopy(&m_nVa, &src.m_nVa);
}
return *this;
}
CVariable& CVariable::operator=(BSTR src)
{
::VariantClear(&m_bsVa);
m_bsVa.vt = VT_BSTR;
m_bsVa.bstrVal = src;
/* or this, if needed:
m_bsVa.bstrVal = ::SysAllocStringLen(src, ::SysStringLen(src));
*/
::VariantClear(&m_nVa);
return *this;
}
If you use the variant_t class instead of VARIANT directly, you can greatly simplify the code while still addressing all of the points mentioned above:
class CVariable
{
public:
CVariable(const CString &strData, int nNum);
CVariable(BSTR bsData);
variant_t GetVariant() const;
private:
variant_t m_bsVa;
variant_t m_nVa;
};
CVariable::CVariable(const CString &strData, int nNum)
: m_bsVa(strData), m_nVa(nNum)
{
}
CVariable::CVariable(BSTR bsData)
: m_bsVa(bsData)
{
}
variant_t CVariable::GetVariant() const
{
return m_bsVa;
}
In this constructor :
CVariable::CVariable(BSTR bsData) {
m_bsVa.vt = VT_BSTR;
m_bsVa.bstrVal = bsData;
}
You are leaving m_nVa uninitialized - it gets some random value. It shall look like this instead:
CVariable::CVariable(BSTR bsData) {
VariantInit(&m_bsVa);
m_bsVa.vt = VT_BSTR;
m_bsVa.bstrVal = bsData;
VariantInit(&m_nVa);
}
And in this constructor:
CVariable::CVariable(CString strData, int nNum)
{
VariantInit(&m_bsVa);
BSTR bsData = ::SysAllocString(strData);
m_bsVa.vt = VT_BSTR;
m_bsVa.bstrVal = bsData;
::SysFreeString(bsData);
VariantInit(&m_nVa);
m_nVa.vt = VT_I2;
m_nVa.lVal = nNum;
}
Do not call ::SysFreeString(bsData); as bsData is owned by m_bsVa.
SysFreeString() frees the memory and the next SysAllocString() call may create a new BSTR string at the same memory address.
Instead of using naked VARIANTs, I'd suggest you use the _variant_t class instead. In this case, you will not need to worry about VariantInit()/VariantClear() at all, as it implements ownership policies in C++ style for you.
I would suggest you to use a convenient C++ RAII wrapper around raw C VARIANTs, like CComVariant from ATL.
This will simplify your code, as CComVariant will properly initialize its wrapped raw VARIANT, and clean it up as well.
You can replace your VARIANT data members with safer CComVariant wrappers:
CComVariant m_bsVa;
CComVariant m_nVa;
Then you can initialize them in constructors like this:
CVariable::CVariable(const CString& strData, int nNum)
: m_bsVa(strData), m_nVa(nNum)
{}
CVariable::CVariable(BSTR bsData)
: m_bsVa(bsData)
{}
Note that you don't need to explicitly define a destructor, as in this case CComVariant's destructor will properly cleanup data members.
Your getter could be implemented like this:
const CComVariant& CVariable::GetVariant() const
{
return m_bsVa;
}

c++ dll, how to write to a double value of a pointer in memory?

I'm facing this problem with trying to write to a pointer to a double in a memory process when I do dll injection.
Here is my class:
class SpeedHack : public MasterClass {
private:
SpeedHack() {};
struct Speed { double speed; };
public:
Speed* getAddy()
{
return (Speed*)(address);
}
bool isSpeedAtkon = false;
void writeMem()
{
getAddy()->speed = 3.1;
}
static SpeedHack& get()
{
static SpeedHack instance;
return instance;
}
};
//address is 0x767650 and value is a double 0.300000
I have also other classes like it and all other work, but I never have double in the structure (only in this class)
The application crashes onceIi try to call writeMemory() method... Other structs from other classes always work even if they are more complex...
logging this : Logger::log("%f", SpeedHack::get().getAddy()->speed); returns me 0.300000 as expected and also logging the address returns me the correct one...
So I don't know what I'm doing wrong... (app crashes once I try to change double value at this address)... does someone know how I could fix it?
ok thanks Bo persson i solved it with this piece of code... i grabbed it from internet, but i dont know all of it is needed :
void doSpeedAtk()
{
DWORD OldProtection;
VirtualProtect((LPVOID)address, 4, PAGE_READWRITE, &OldProtection);
getAddy()->speed = 3.1;
VirtualProtect((LPVOID)address, 4, PAGE_READWRITE, &OldProtection);
}

Lua C++ userdata

I am trying to access the type of a userdata so that I can process it accordingly. Imagine I have a class named as Foo:
class Foo:public CObject
{
public:
Foo():CObject(){}
int type() {return 1;}
}
class CObject
{
public:
virtual int type(void)=0;
}
The rationale is that every class extending the CObject has a type that must be made known by an integer number (later on an enum). The class Foo is bind to lua using luaWwrapper (//https://bitbucket.org/alexames/luawrapper/src/fd9c4fdbf4b25034e3b8475a2c8da66b7caab427?at=default).
Foo* Foo_new(lua_State* L)
{
Foo* f=new Foo();
lua_newuserdata(L,sizeof(f));
std::cout<<"f="<<f;
return f;
}
In Lua user calls this as:
f=Foo.new()
print(f)
Now I have a C++ function, say print:
int lua_print(lua_State* L)
{
void *ud = luaL_checkudata(L, 1, "Foo"); //ud is not zero
std::cout<<"ud="<<ud;
CObject* obj=(CObject*)ud; //Casting to CObject
int objtype=obj->type(); //program CRASHES here
}
I have seen that the program crashes cause the memory addresses of Foo and ud are not the same. I assume ud refers to the memory of stack which contains the memory adress of Foo. How can I access stack's memory address or the preferred memory address of Foo?
You have to use placement new to initialize the object in the memory returned by lua_newuserdata.
Something in the lines of
void *ud = lua_newuserdata(L,sizeof(Foo));
new (ud) Foo();
Foo_new should just return the pointer to the object.
In other words, your Foo_new would look like this:
Foo* Foo_new(lua_State* L)
{
return new Foo();
}
However, if you have no special initialization you need to do, you don't even need to write this function. This function is supplied for you by magical templates if you don't write one yourself.
When you want to get your Foo object from the Lua state, you do this:
int lua_print(lua_State* L)
{
Foo *ud = luaW_to<Foo>(L, 1); //ud is not zero
std::cout<<"ud="<<ud;
CObject* obj=(CObject*)ud;
int objtype=obj->type();
}
If CObject is registered with LuaWrapper too, you don't even need to do the manual cast. You can just do luaW_to<CObject>(L, 1);

Polymorphism/inheritance issue with virtual class member function

I might have the wrong idea on exactly what polymorphism versus inheritance is, but basically what I'm trying to do is have classB derive from classA, and create a classB which overrides a pure virtual member function of classA, like so:
classA:
/////////////////
// CodeBlock.h //
/////////////////
typedef enum {
CCBT_UNDEFINED,
CCBT_FUNCTION,
//...
} CODE_BLOCK_TYPE;
class CCodeBlock {
public:
CCodeBlock::CCodeBlock();
CCodeBlock::CCodeBlock(CString& source, DWORD startPos);
CCodeBlock::~CCodeBlock();
virtual CODE_BLOCK_TYPE CCodeBlock::GetType() = 0
CString m_code;
DWORD m_startPos;
DWORD m_length;
int m_numLines;
}
///////////////////
// CodeBlock.cpp //
///////////////////
//...
CCodeBlock::CCodeBlock(CString& source, DWORD startPos) : m_code(source), m_startPos(startPos) {
m_length = m_code.GetLength();
}
CODE_BLOCK_TYPE CCodeBlock::GetType() {
return CCBT_UNDEFINED;
}
classB:
/////////////////////
// FunctionBlock.h //
/////////////////////
#include "CodeBlock.h"
class CFunctionBlock : public CCodeBlock {
public:
CFunctionBlock::CFunctionBlock();
CFunctionBlock::CFunctionBlock(CString& source, DWORD startPos);
CFunctionBlock::~CFunctionBlock();
CODE_BLOCK_TYPE CFunctionBlock::GetType();
}
///////////////////////
// FunctionBlock.cpp //
///////////////////////
//...
CFunctionBlock::CFunctionBlock(CString& source, DWORD startPos)
{
m_code = source;
m_startPos = startPos;
}
CFunctionBlock::~CFunctionBlock()
{
CCodeBlock::~CCodeBlock();
}
CODE_BLOCK_TYPE CFunctionBlock::GetType()
{
//////////////////////////////
// >> NEVER GETS CALLED! << //
//////////////////////////////
return CCBT_FUNCTION;
}
main:
CCodeBlock *block = new CFunctionBlock(L"function hello(){ print('hello') }", iPos)
CODE_BLOCK_TYPE type = block->GetType(); // ALWAYS RETURNS CCBT_UNDEFINED!
As you can see, GetType() always returns CCBT_UNDEFINED. Keep in mind that CCodeBlock is meant to be a 'generic' version of CFunctionBlock (as well as a few other like-minded classes, some of which contain a CCodeBlock 'm_parent' member variable), and is supposed to inherit any CCodeBlock member variables & member functions, as well as override a specific list of functions contained in CCodeBlock.
How can this be achieved? Would I need to resort to using templates (if that's even possible)?
Bring comment as answer:
you don't need CCodeBlock:: when you declare member functions inside class CCodeBlock
There are several things wrong with your code. Member declarations should not have the class name as qualification (i.e. CCodeBlock:: should be removed from the declarations). Leaving it there makes the code ill formed.
Besides that, the destructor of a derived type will implicitly call the base class' destructor, and you should not do it. If you call it manually, the base subobject will be destroyed twice, probably causing undefined behavior (if the base destructor is not trivial).
Now the particular issue with your code in main was probably more like this:
CCodeBlock *block
= new CFunctionBlock(L"function hello(){ print('hello') }", iPos)
CODE_BLOCK_TYPE type = block->CCodeBlock::GetType();
// ^^^^^^^^^^^^
In C++, qualifying a function call disables dynamic dispatch. The expression block->GetType() will be dispatched to the final overrider of the dynamic type of the object that the block pointer points to. But if you add the qualification: block->CCodeBlock::GetType() you are asking the compiler to call the overrider at the CCodeBlock level.

Polymorphism determination issue

I have a problem I am working on. I have a number classes which inherit each other in this pattern:
#include <stdio.h>
#include <stdlib.h>
#include <list>
class TimeObject
{
public:
virtual void Tick()=0;
std::list<TimeObject*> ticks;
};
class MapObject : public TimeObject
{
public:
MapObject()
{
ticks.push_front(this);
printf("Create MapObject %p\n", this);
}
void Tick() { printf("mapobject tick\n"); }
};
class ControlObject : public MapObject
{
public:
ControlObject()
{
ticks.push_front(this);
printf("Create ControlObject %p\n", this);
}
void Tick() { printf("controlobject tick\n"); }
};
int main()
{
ControlObject test;
std::list<TimeObject*>::iterator it = test.ticks.begin();
for(; it != test.ticks.end(); it++)
{
TimeObject *trigger = *it;
trigger->Tick();
}
return 0;
}
The list in the example stores any TimeObject derived class. My problem is that when storing MapObject pointers in the list that are also ControlObjects dispatch always picks the ControlObject function.
Is it possible to trigger the MapObject function with a ControlObject pointer using polymorphism? If it isn't possible/pratical, what would be a good alternative?
You should always store pointer to the Base class A* in the list(std::list< A*>).
The pointer should be correctly made to point either a object of type Bor C before you add the pointer to the container.
Once you do that, dynamic dispatch will take care of calling the correct function for you depending on the actual object type. You don't need to do anything.
I don't know why you want to have any design which is otherwise, If you have any good reasons to do so please let know of them.
Why it always calls ControlObject::tick() in your code?
When you call:
ticks.push_front(this);
in ControlObject::ControlObject() you basically end up overwriting the first pointer you added to the list, The type of the first pushed pointer is not MapObject * anymore it is ControlObject * because you changed the pointer behind its back.You did not transfer ownership of the pointer to the list but you both had shared ownership and you modified the object in your list through the constructor call in derived class. This leaves you with two ControlObject * objects in the list which dynamic dispatch correctly determines and calls the correct method.
There is nothing wrong in what dynamic dispatch does, it is the correct behavior.
If you want to call MapObject::Tick(); then you will explicitly have to tell the compiler to do so, dynamic dispatch works on the actual type of object and it is working correctly.
void controlobject::Tick()
{
printf("controlobject tick\n");
MapObject::Tick();
}
Replicating from the comments:
I am afraid this is a bad design.The code works as it should,it works as defined by the C++ standard.The problem lies in the design.And unless you provide the details of what you are trying to achieve in a broader sense it is difficult and rather pointless to speculate on a new design.
Using a cast on the variable of type C to the type B should do the trick.
C c;
B b;
c.Function();
((B)c).Function();
A * l[] = {&c,&b,&c};
l[0]->Function();
l[1]->Function();
l[2]->Function();
B test = *(B*)l[0];
test.Function();
In your current example you should be able to call both virtual members (or just the one depending on the underlying type) by calling MapObject::Tick() inside ControlObject::Tick():
class ControlObject : public MapObject
{
public:
ControlObject()
{
ticks.push_front(this);
printf("Create ControlObject %p\n", this);
}
void Tick() { printf("controlobject tick\n"); MapObject::Tick(); }
};
The explicit function call notation is required.