|
Since there are many functions in picture I think you should go for COM. Using COM will turn out to be simpler.
|
|
|
|
|
I have an out-proc server i'm currently writing. In this server I have a number of interfaces. I was wondering if I could do the following. All the interfaces and implementations of the interfaces are in the same project.
interface IUser {....}; // IUser definition
interface IUsers {....}; // IUsers definitions
class CUser : public IUser {....}; // The implementation of IUser
class CUsers : public IUsers {...}; // The implementation of IUsers
HRESULT CUsers::SomeFunc() {
CComPtr<IUser> pUser;
pUser.CreateInstance(__uuidof(IUser));
((CUser*)(pUser.p))->m_SomeData; // Can I do this cast from IUser to CUser?
...
}
That was my question, is the cast possible?
Justin Turney
|
|
|
|
|
Yes, but it is not safe.
Since you are in your CUser class when you create the new object, it would be safer to call new, then cast the object to the interface if the interface needed to be exported from the function.
HRESULT CUsers::SomeFunc()
{
CUser pUser = new CUser;
pUser->m_SomeData;
...
CComPtr piUser
piUser = static_cast<IUser*>(pUser);
...
}
Good Luck
Build a man a fire, and he will be warm for a day Light a man on fire, and he will be warm for the rest of his life!
|
|
|
|
|
Justin Turney wrote:
That was my question, is the cast possible?
Why do you want to do that?
You should never do anything like that. If a proxy or stub gets involved in between then the code will not be safe.
|
|
|
|
|
Can't you implement a propget on IUser that returns the contents of m_SomeData?
|
|
|
|
|
pUser.CreateInstance(__uuidof(IUser));
__uuidof(IUser) is the UUID of IUser interface, not the his coclass CLSID. So this call will be unsuccessful.
You can use the local creation of COM object:
CComObject < CUser >* pUser;
HRESULT hr = pUser->CreateInstance( & pUser );
if( SUCCEEDED(hr) )
{
pUser->m_SomeData;
...
delete pUser;
}
With best wishes,
Vita
|
|
|
|
|
I get the impression that most plugins are implemented using COM, hence the posting here. Can anyone give me any headstart on implementing plugins in my application. OpenSource examples would be particularly useful.
Any tips or hints?
I Cargill CEng BENg MBCS
|
|
|
|
|
I have trouble creating instance of an shellwindows object in MFC dll
CreateInstance does not work in MFC DLL, but CreateInstance work well in EXE MFC
It hangs on the CreateInstance row
What could this be happening ?
/// My code //
// I Created a Dialog class in MFC DLL
BOOL CWalletDlg::ShellWindowAdvise()
{
EnableAutomation();
m_pIE5Events = new CIE5Events(this);
HRESULT hr = 0;
CoInitialize(NULL);
if (m_spSHWinds == 0) {
hr = m_spSHWinds.CreateInstance(__uuidof(SHDocVw::ShellWindows));
AfxConnectionAdvise( m_spSHWinds,
__uuidof(SHDocVw:ShellWindowsEvents),
this->GetInterface( &IID_IUnknown ),
TRUE, &m_dwCookie );
return TRUE;
}
}
|
|
|
|
|
Is the exe calling CoInitialize?
|
|
|
|
|
More importantly, is the EXE calling CoInitialize on the thread that the DLL is loaded.
Build a man a fire, and he will be warm for a day Light a man on fire, and he will be warm for the rest of his life!
|
|
|
|
|
I have a little problem. The background is:
I'm working on a server/client application in C# and I want to setup up a session, but when you use COM+ you can't use a session. The client is not run in a browser.
I also have to "create" the session on the server and pass it on to the client. Anyone have a suggestion on how to implement this (NOT in ASP)?
I've been trying to com up with some constructive solution for a while now, but i hit the wall before i get any results!
MikeC#
|
|
|
|
|
Is that a way to pass simple functions to COM objects like this:
ob->Method(pFunc);
where pFunc is a function like "void pFunc(void)"?
I want pFunc to be called from inside the COM object.
rechi
|
|
|
|
|
It is not considered a good practice to pass pointers in COM methods. Instead wrap the function as an interface
interface IMyFunc
{
HRESULT Func();
}
Just to give you an idea.
You can have
class A : IMyFunc
{
public:
void Func()
{
}
}
The method would look like
HRESULT Method(IMyFunc* pFunc);
A* pA;
.
.
.
ob->Method(pA);
|
|
|
|
|
It's what i was the most afraid of: interfaces wrapping functions. Unfortunately this solution consumes a large amount of time.
Thanx!
rechi
|
|
|
|
|
Bogdan Rechi wrote:
Unfortunately this solution consumes a large amount of time.
That is the price that we all have to pay for Binary Comaptible code.
Build a man a fire, and he will be warm for a day Light a man on fire, and he will be warm for the rest of his life!
|
|
|
|
|
A better choice for this than wrapping the function in an interface to create an Event sink for your COM object.
Then users of your object can register with your object for certain events. Then when that event occurs your object will call all of the event sink functions that have been registered with your object. This is a very efficient way to solve your problem.
There are a lot of good examples in MSDN and there might be a few on CP.
Build a man a fire, and he will be warm for a day Light a man on fire, and he will be warm for the rest of his life!
|
|
|
|
|
I need pass an array of data in a variant to an API call. I'm not sure if I'm passing the data correctly as I'm new to COM.
I appreciate if someone could verify the below snippet has a obvious problem when using COM arrays because the API call does not produce the intended results with the array data I passed.
// generate 3 element array of floats
SAFEARRAY *psa = SafeArrayCreateVector( VT_R4, 0, 3 );
float HUGEP *dp = 0;
SafeArrayAccessData( psa, (void HUGEP**)&dp );
dp[0] = 6;
dp[1] = 7;
dp[2] = 8; // set array to 6,7,8
SafeArrayUnaccessData( psa );
VARIANT va;
va.vt = VT_ARRAY | VT_R4;
va.parray = psa;
// pass va to API that takes a variant
Blah( va );
SafeArrayDestroy( psa );
|
|
|
|
|
Did you try to pass it as a reference instead?
va.vt = VT_ARRAY | VT_BYREF | VT_R4;
va.pparray= &psa;
Your code seems to work fine other than that!
What API are you using? the way it expects to
receive your data is also important.
One good thing about getting older, you don't lose the ages you've been!
|
|
|
|
|
Ernest Laurentin wrote:
Did you try to pass it as a reference instead?
Yup, didn't work too.
The API is a Avid SoftImage XSI v2 SDK. It has virtually ZERO documentation so I'm guessing how to call it by looking at headers and vbscript examples.
The vbscript version works like this
<br />
Blah( array(5,6,7) )<br />
The C++ version is defined as
<br />
virtual HRESULT STDMETHODCALLTYPE Blah( <br />
VARIANT in_pNewEffPos );<br />
The worst part is the API runs successfully (HR succeeded) but the results are wrong.
I'm not well experienced enough with COM or I would have condemn it as a bug with their API straight away.
|
|
|
|
|
Sorry it took me long to write you!
Did you try to send "long" or "short" array?
You example here both integer value not float. Maybe
the API accepts integer value not float!
One good thing about getting older, you don't lose the ages you've been!
|
|
|
|
|
Ernest Laurentin wrote:
Maybe
the API accepts integer value not float!
Thanks for the reply.
Quite impossible. It should be taking either float or double because in the UI, one can enter decimal places for the values. They can't be using fixed point maths.
But I will try again just to make doubly sure.
|
|
|
|
|
I see... but I still think if you can make it work with
VBScript, you can implement the same in C++. Did you try
to reproduce simple code in VB? For example:
dim vbArray(3)
dim nloop
for nloop = 0 to 3
vbArray(nloop) = nloop+4 ' or other value
next
Blah( vbArray )
The reason I will do it like this instead to do just call:
Blah( array(5,6,7) ) is that I am not really sure
how VB interprets that line. But you should be able to reproduce
the same type of array (dim vbArray as "type").
Good luck!
One good thing about getting older, you don't lose the ages you've been!
|
|
|
|
|
That's a very good idea you have there. Unfortunately (fortunately?), it's weekend party and I have to wait till next week to try it out.
Thanks for your time. Very appreciated.
|
|
|
|
|
Fortunately for you, I guess! Keep in touch! Have great time!
One good thing about getting older, you don't lose the ages you've been!
|
|
|
|
|
Ah, I spotted an mistake
It should be
<br />
Dim vbArray(2)<br />
instead of
<br />
Dim vbArray(3)<br />
because for reasons I cannot fathom, vbArray(2) means a 3 element array.
Anyway, the vbscript in the form above works. I am unable to explicitly declare the dim type though. Dim vbArray(2) As Double generates an "Expected end of statement" error. This seems to be more of the scripting environment problem rather than mine.
|
|
|
|