|
Hi,
I build a singelton comobject, to be a 'meetingpoint' for different processes located on remote computers.
I've got a method called:
[id(2), helpstring("method ConnectMachine")] HRESULT ConnectMachine([in] IUnknown* pUnk, [in] BSTR strMachineName);
which connects a client to the meetingpoint and passes an interfacepointer to an interface implemented on the client, for callbacks.
The 'meetingpoint' objects saves the machinename and the interfacepointer
in a list for every connected machine.
If I now use this interfacepointer to call methods on a client this is no problem, and works well.
But i want to go a little further, and want to retrieve an interfacepointer from one client to another over the meetingpoint by a method called:
[id(3), helpstring("method GetMachineInterface")] HRESULT GetMachineInterface([in] BSTR strMachineName, [out] IUnknown** ppvObject);
which should retrieve an interfacepointer by the machinename.
If I try this, a get the errormessge "invalid access to memory location" on the client side.
Does anybody known why?
Thanks for help!
Elch
|
|
|
|
|
Can you give a sample how client handles return values from
"HRESULT GetMachineInterface([in] BSTR strMachineName, [out] IUnknown** ppvObject);" ?
|
|
|
|
|
Of course,
try
{
hr = m_pIMachineConnectionPoint->GetMachineInterface("TESTMACHINE", &pUnk);
if (pUnk)
{
IMachine* pMachine;
hr = pUnk->QueryInterface(__uuidof(IMachine), (void**)&pMachine);
if (SUCCEEDED(hr))
pMachine->StartProductionMode();
}
}
catch (_com_error e)
{
// here I get the error message: "Invalid access of memory location"
....
I think it has something to do with marshalling,or??
Thanks!
elch
|
|
|
|
|
GUESS 1
If you do not mind change
"if(SUCCEEDED(hr))"
to
"if (SUCCEEDED(hr) && 0 != pMachine)"
If I am right Query interface returns null pointer
GUESS 2
Inspect ( and publish here if possible for me to examine) StartProductionMode() code, I suspect there is uninitialized pointer.
|
|
|
|
|
Sorry, I didn't mentioned that if I try to execute the line:
hr = m_pIMachineConnectionPoint->GetMachineInterface("TESTMACHINE", &pUnk);
then an exception occures, and I get the error "Invalid acces to memory location" from e.ErrorMessage().
I think the has something to do with marshalling, because the interfacepointer stored in the list of the meetingpoint object, is marshalled to the machine on which the meetingpoint object is running. And I do not know if COM automatically remarshalls the pointer for the third machine??
-----------------
| |
| meetingpoint |
------------- | IpointerList | -------------
| |----------------------| |--------------------| |
| Machine 1 | ----------------- | Machine 2 |
| | | |
------------- -------------
Machine 1 and 2 are connecting to meetingpoint object and interfacepointers are stored in Ipointerlist.
Client:
m_pIMachineConnectionPoint->ConnectMachine(pUnk, m_MachineName.AllocSysString());
Then machine1 tries to get an interfacepointer from Ipointerlist of machine2, I'm not really sure if COM automatically remarshalls the interfacepointer to point directly to machine 2.
Thanks!
|
|
|
|
|
It should remarshal it (I think ), if not you can easily do it yourself (CoMarshalInterface) . The reason I am not totally convinced is that the error code is nothing like marshaling, it seems you have some un-initialized pointer. If it is ConnectMachine I would put a lot of tracing logic in it to see exactly what breaks.
|
|
|
|
|
The first parameter of GetMachineInterface is a BSTR one. Therefore you need to pass strictly BSTR value, not char* or wchat_t*.
BSTR machname = SysAllocString(L"TESTMACHINE");
hr = m_pIMachineConnectionPoint->GetMachineInterface( machname, &pUnk);
SysFreeString( machname );
or
hr = m_pIMachineConnectionPoint->GetMachineInterface( bstr_t(L"TESTMACHINE"), &pUnk);
or
hr = m_pIMachineConnectionPoint->GetMachineInterface( CComBSTR(L"TESTMACHINE"), &pUnk);
With best wishes,
Vita
|
|
|
|
|
I believe this is your problem. You should also change the following code:
if (pUnk)
to
if (SUCCEEDED(hr))
John
|
|
|
|
|
i want to write a simple addin for VS.NET, which comments(like //##MYNAME**NR2003##//) the selceted lines of code.
this is all finde and easy, but i have now a hughe problem:
if "selction margin" is switched on (under tools/ options/texteditor), then the addin does not work properly, when selecting code, that contents of outlined code.
when i make things like:
pTextSelection->get_CurrentLine(&lCurrLine);
pTextSelection->get_TopLine(&lTop);
pTextSelection->get_BottomLine(&lBottom);
i get only the linenumbers of the code currently visible on the screen. but i also want the numbers of the lines who are outlined!
how can i do this???? i didnt found any function!
the only function i found is the one to outline code
(->OutlineSection) but i would like to do the contrary!!!
please help me!
thanx, andreas
|
|
|
|
|
Hi all,
I have a stupid problem but I do not know if it can solved some way. While trying to compile a ATL/COM component, I want the MIDL compiler include some other .idl files stored in a path like C:\Program Files\DanLoad 6000\Include.
So I put the project settings for MIDL compiler with the /I option (/I "C:\Program Files\Danload 6000\Include").
When I try to build the project, I get the follwoing error. It look as if the MIDL compiler does not understand blanks in the path for include files.
Anyone can help?
Thank you in advance.
--------------------Configuration: DldDanload6000 - Win32 Debug--------------------
Creating Type Library...
Microsoft (R) MIDL Compiler Version 5.01.0164
Copyright (c) Microsoft Corp 1991-1997. All rights reserved.
Processing C:\temp\DldDanload6000\DldDanload6000.idl
Danload
fatal error C1083: Cannot open source file: 'Files\Danload': No such file or directory
6000
fatal error C1083: Cannot open source file: '6000': No such file or directory
Include
fatal error C1083: Cannot open source file: '6000\Include': No such file or directory
DldDanload6000.idl
midl : command line error MIDL1003 : error returned by the C preprocessor (2)
Error executing midl.exe.
DldDanload6000.dll - 4 error(s), 0 warning(s)
_________________________________________________________________________
|
|
|
|
|
Why do you want to include the .idl file? Do you need the interface declarations of other some other coclasses? One solution is to include the .c and .h files.
Kuphryn
|
|
|
|
|
Difficult to say - but just a wild guess - if you put the /I "C:\Program Files\Danload 6000\Include" option, it will receive the path as:
C:\Program Files\Danload 6000\Include
from the command line. And when it is just passed to another procedure or where, it might be misunderstood.
I would try:
/I """C:\Program Files\Danload 6000\Include"""
or something similar, just to achieve the effect, that the MIDL will receive
"C:\Program Files\Danload 6000\Include"
instead of mentioned
C:\Program Files\Danload 6000\Include
Maybe this helps...
|
|
|
|
|
I'm interested to know if this one works, because I'm having the same problem passing a response file name to the csc.exe compiler.
"Do unto others as you would have them do unto you." - Jesus
"An eye for an eye only makes the whole world blind." - Mahatma Gandhi
|
|
|
|
|
Hi,I have a MFC client to access COM server install in a COM+ app on another machine,and it seem runs well ,but during a long time it thow an error with code 0x80010005.there is an article on MSDN "INFO: COM Method Call in WM_PAINT Handler Returns 0x80010005" ,my code didn't call com server in OnDraw nor in WM_PAINT handler.but the phenomenon even go.
I am very puzzle and have no idea about it.
Help me please!
|
|
|
|
|
"It is illegal to call out while inside message filter", does this make sense?
|
|
|
|
|
Hello,
i am creating an EXE com server through ATLCOMAppWizard. i inserted a NEWAtlObject through insert->newatlobject,i selected simple object then i prefered custom interfaces in attributes and checked the option of support Error information & connection points. i added more interfaces to the object by adding code to .IDL file &compiled it & made necessary changes to cpp file .
finally when build the project i got everything successful & the message of successfully registered component.
i am facing problem to create a client to that EXE-server, i cann't create object via CoCreateInstance though i included MIDL-generated .h &_i.c files in the client code.
please help me in creating client to the above EXE-server.If possible please send a example of EXE-client code.
satish silla
Larsen & Tubro Ltd,
Mumbai.
|
|
|
|
|
What is the error?
Make sure the remote server has been registered in the registry.
Kuphryn
|
|
|
|
|
i have seen the coclass is registered in the registry under the key HKEY-CLASSES-ROOT\CLSID\ .also at the time of building the project the result showing registation successful. one thing that i can n't find the IID of interfaces under the key HKEY_CLASSES_ROOT\interfaces\.
i am also in doubt how to create a client to exe-servers.i won't face the same problem in DLL-servers.
thanking u for trying to answer me
|
|
|
|
|
I created a simple activeX control in VB that has a single method that raises an event and passes back three params in the event. I have modded a c++ ATL client app that I found here (THANKS!) that processes the event. When the third event parameter is specified as type "SINGLE" in VB and float in c++, the printf works correctly (returns 302,429.0,460.0). When I change the third param to type "Double" in bothe the control and the C++ client, the values seem to be corrupted (302, -107374176.0, 5.6e-315) - even seems to corrupt the 2nd param (a single). Is there something different about passing doubles versus singles?
vb Code:
<br />
Public Event paramsback(ByVal x As Long, ByVal y As Single, ByVal z As Double)<br />
<br />
Public Sub PassItIn(ByVal x As Long, ByVal y As Single, ByVal z As Double)<br />
<br />
RaiseEvent paramsback(x, y, z)<br />
<br />
End Sub<br />
C++ app:
<br />
#include "stdafx.h"<br />
#include <stdio.h><br />
<br />
#import "ABIG_VBOCXTEST.ocx" no_namespace named_guids<br />
<br />
CComModule _Module;<br />
<br />
interface CSink:public IDispEventImpl<0, CSink, &DIID___mytestcontrol, &LIBID_ABIG_VBOCXTEST, 6, 0><br />
{<br />
public:<br />
<br />
BEGIN_SINK_MAP(CSink)<br />
SINK_ENTRY_EX(0, DIID___mytestcontrol, 0x1, Onparamsback)<br />
END_SINK_MAP()<br />
<br />
HRESULT __stdcall Onparamsback(long x, float y,double z)<br />
{<br />
printf("Event = %d,%6.2f,%6.2g",x,y,z);<br />
<br />
return S_OK;<br />
}<br />
};<br />
<br />
void main()<br />
{<br />
CoInitialize(NULL);<br />
<br />
_Module.Init(NULL, GetModuleHandle(NULL));<br />
<br />
_mytestcontrolPtr server;<br />
<br />
server.CreateInstance(CLSID_mytestcontrol);<br />
<br />
CSink sink;<br />
<br />
sink.DispEventAdvise(server);<br />
<br />
server->PassItIn(302,429.0,460.0);<br />
<br />
sink.DispEventUnadvise(server);<br />
<br />
server.Release();<br />
<br />
<br />
_Module.Term();<br />
<br />
CoUninitialize();<br />
}<br />
stdafx.h:
<br />
<br />
#if !defined(AFX_STDAFX_H__70227B2B_B9C9_4FC9_A100_2619AB307158__INCLUDED_)<br />
#define AFX_STDAFX_H__70227B2B_B9C9_4FC9_A100_2619AB307158__INCLUDED_<br />
<br />
#if _MSC_VER > 1000<br />
#pragma once<br />
#endif // _MSC_VER > 1000<br />
<br />
#define _ATL_MAX_VARTYPES 16<br />
<br />
#include <atlbase.h><br />
extern CComModule _Module;<br />
#include <atlcom.h><br />
<br />
<br />
<br />
#endif // !defined(AFX_STDAFX_H__70227B2B_B9C9_4FC9_A100_2619AB307158__INCLUDED_)<br />
stdafx.cpp
<br />
#include "stdafx.h"<br />
|
|
|
|
|
|
Yes it can. But I can help you only with ATL - don't have a clue how to do it with MFC. The events are in fact standard methods as any other, so you have just to mark the parameter as [out] or [out,retval] . That's all in IDL.
But if you are using ATL, there's a little need to change the generated Fire_OnMyEvent method. Understanding what's going on inside the method is the key to the success
On beginning there's created a new array of CComVariant s. Later on, all parameters are copied(!) to this array. And you need to change exactly this behavior - there are several ways...
What you can use is instead of copying the value, use the already existing variant in an array and turn him to the reference to your out parameter (VT_BYREF flag can be handy). But any other method can be also usefull and working - it's up to you to decide how you want to do it.
|
|
|
|
|
Hi,
I am learner of COM Technology.I have written simple com object.It has 3 methods.I compiled it successfully.But the problem is I have written client program,it is showing errors.
i have included component's .h,_i.c files into client program
CoInitialize(NULL);
CoCreateInstance(..........);
what are the steps to follow to write COM Client program.
yakkalas
|
|
|
|
|
Did you register the COM server to registry? What is the error?
Kuphryn
|
|
|
|
|
hi,
yah registered COM Server to registry.
atlwin.h requires atlbase.h to be included first
|
|
|
|
|
Did you use the ATL wizard?
What is the error yu get?
R.Balachandran
|
|
|
|