|
My client who is using our library written in COM, need to use multi-threads to access our library. However, he needs to call AfxOleInit() in his application.
Is there any way around this?
I have tried calling CoInitializeEx in worker threads (and the main thread calls AfxOleInit() ), but it doesn't work. The worker threads couldn't access our library as the COM apartment is single thread even through he specified COINIT_MULTITHREADED for the 2nd parameter of CoInitializeEx() call.
|
|
|
|
|
CBasicNet wrote:
The worker threads couldn't access our library as the COM apartment is single thread even through he specified COINIT_MULTITHREADED for the 2nd parameter of CoInitializeEx() call.
What exactly do you mean with "access our library"? If you are trying to access an interface pointer, created in one apartment, from another apartment, everything will fail. You must first marshal the interface pointer to the apartment where you want to use it. Please see this article[^].
--
Wir müssen leben bis wir sterben.
|
|
|
|
|
Hi!
I implement IOleCommandTarget in a .net COM server.
Here's my code. I'm trying to implement an object that can be used as a
COM object for a button in IE. I get a System.ExecutionEngineException when hitting the button (.
---------------------------------implement------------------------------------------
// Import IOleCommandTarget interface
[StructLayout(LayoutKind.Sequential,CharSet=CharSet.Unicode)]
public struct OLECMDTEXT
{
public uint cmdtextf;
public uint cwActual;
public uint cwBuf;
[MarshalAs(UnmanagedType.ByValTStr,SizeConst=100)]public char rgwz;
}
[StructLayout(LayoutKind.Sequential)]
public struct OLECMD
{
public uint cmdID;
public uint cmdf;
}
// Interop definition for IOleCommandTarget.
[ComImport,
Guid("b722bccb-4e68-101b-a2bc-00aa00404770"),
InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IOleCommandTarget
{
void QueryStatus(ref Guid pguidCmdGroup, UInt32 cCmds,
[MarshalAs(UnmanagedType.LPArray, SizeParamIndex=1)] OLECMD[] prgCmds, ref OLECMDTEXT CmdText);
void Exec(ref Guid pguidCmdGroup, uint nCmdId, uint nCmdExecOpt, ref object pvaIn, ref object pvaOut);
}
-----------------------------------implement----------------------------------------
-----------------------------------using----------------------------------------
[ClassInterfaceAttribute(ClassInterfaceType.None)]
[GuidAttribute("81AC67A9-1511-4104-93AC-BD8BFEC93F71")]
[ProgIdAttribute("MyDll.dll")]
public class GetURL: IObjectWithSite, IOleCommandTarget
{
protected SHDocVw.IWebBrowser2
m_pIWebBrowser2; // the browser class object
public GetURL()
{
}
public void SetSite(object pUnkSite)
{
// MessageBox.Show("SetSite");
if (m_pIWebBrowser2!=null)
Release();
if (pUnkSite==null)
return;
IServiceProvider isp = (IServiceProvider)pUnkSite;
try
{
//!!!!!получаем указатель на SHDocVw.IWebBrowser2 через IServiceProvider а не QueryInterface
Guid g1 = typeof(SHDocVw.IWebBrowserApp).GUID;
Guid g2 = typeof(SHDocVw.IWebBrowser2).GUID;
object obj;
//isp.RemoteQueryService( ref g1, ref g2, out m_pIWebBrowser2 );
isp.QueryService( ref g1, ref g2, out obj );
//получили объект и преобразуем его к SHDocVw.IWebBrowser2
m_pIWebBrowser2 = (SHDocVw.IWebBrowser2)obj;
}
catch(System.Runtime.InteropServices.COMException ex)
{
//
}
MessageBox.Show(m_pIWebBrowser2.ToString());
}
public void GetSite(ref System.Guid riid, out object ppvSite)
{
ppvSite = m_pIWebBrowser2;
try
{
//
}
catch(Exception ex)
{
MessageBox.Show(ex.Message + " GetSite");
}
}
public void QueryStatus(ref Guid pguidCmdGroup, UInt32 cCmds, OLECMD[] prgCmds, ref OLECMDTEXT CmdText)
{
MessageBox.Show ("Query status");
}
public void Exec(ref Guid pguidCmdGroup, uint nCmdId, uint nCmdExecOpt, ref object pvaIn, ref object pvaOut)
{
MessageBox.Show ("Execing");
}
}
-----------------------------------using----------------------------------------
In what a mistake? Help! Plz!!
|
|
|
|
|
Hi,
I’ve got a strange behaviour of DCOM on Windows 2003 Server. I’ve created COM-server (out-of-process) and COM-client for that COM-server. Both work successfully on local computer under any operation system. Also server and client work fine when COM-server is installed on Windows 2003 Server and when COM-client works on other PC running Windows XP.
When I try run COM-server on Windows XP and COM-client on Windows 2003 Server, COM-client told me “Can’t query COM-server at remote PC: Permission denied”.
Windows XP and Windows 2003 Server are located at the same network and at the same workgroup (not used domains). All permissions are set by default.
What should I do? Here is the sample code of COM-client:
CoInitializeEx(NULL,COINIT_MULTITHREADED);
IReqAuth * pReqAuth;
WCHAR *wszMachineName=L"ALPHA\0";
COSERVERINFO srv;
ZeroMemory(&srv,sizeof(srv));
srv.pwszName=wszMachineName;
MULTI_QI qi;
qi.pIID=&IID_IReqAuth;
qi.hr=0;
qi.pItf=NULL;
HRESULT hr=CoCreateInstanceEx(CLSID_ReqAuth,
NULL,
CLSCTX_SERVER,
&srv,
1,
&qi);
if (SUCCEEDED(hr))
{
pReqAuth=(IReqAuth *)qi.pItf;
printf("COM object OK\n");
char szTmp[MAX_PATH];
BSTR AppVersion;
hr=pReqAuth->GetVersion(&AppVersion);
if (SUCCEEDED(hr))
{
memset(szTmp,0,sizeof(szTmp));
wcstombs(szTmp,AppVersion,SysStringLen(AppVersion));
printf("AppVersion: %s\n",szTmp);
SysFreeString(AppVersion);
}
else
{
sprintf(szTmp, "GetVersion failed hr = %x\n", hr);
printf(szTmp);
};
pReqAuth->Release();
}
else
{
printf("Error creating COM-object %d\n",GetLastError());
};
::CoUninitialize();
Sleep(200);
Please help, my brains can’t think anymore.
Sincerely Yours,
RadioShark
|
|
|
|
|
juz go thru the links below..
1[^]
2[^]
rgds..mil10
|
|
|
|
|
I am a newbee on .Net C++. Just bought it.
Reading the book. Read the (short) chapter
on COM. Basically it said, one can keep ones
COM code. My question... Is there a BETTER
way in .Net?
I have a application with COM supplied solutions
to common user needs.
As I am moving to .Net -- I have the opportunity
to provide those solutions through .Net rather
than via COM servers.
A recommendation of where to read would be
appreciated.
WedgeSoft
|
|
|
|
|
Good Question. My impression is that .NET took the best concepts that COM developed and incorporated them into it's internal structure. There are profound differences, though. In his book, ".NET and COM: The Complete Interoperability Guide", Adam Nathan describes the .NET Framework as an evolution of COM. I recommend you read that book, it thoroughly describes writing code that understands how to interoperate in both the 'COM world' and the '.NET world'. The engineers at Microsoft put alot of work into making COM type libraries operate in managed applications as if they were .NET components.
There are some HUGE differences, though. You'll notice immediately that the types are considerably different, and marshaling data between two disparate types is difficult. The .NET compiler includes some excellent utilities to help the developer with COM interop. Check out the The OLE/Object Viewer, the Type Library Importer (TypImp.exe) and the IL Disassembler.
|
|
|
|
|
need to know some COM stuff, can someone kindly recommend a good/popular COM/COM+ book?
|
|
|
|
|
I got a good deal out of Developers's Workshop to
COM and ATL 3.0 by Andrew W. Troelsen. I knew
nothing about COM -- read the book and did the
exercises. Now my project has COM support.
(This is a beginners COM book; but not for
beginner C++ programmers.)
Modified:
(And read the reply to my question about a
.Net alternative to COM -- there Zeta makes
a recommendation to me.)
WedgeSoft
|
|
|
|
|
One of the principal references for COM is: "Essential COM", by Don Box, published in 1998. He writes for the C++ developer (all the code examples are C++). But, he explains everything clearly and thoroughly. Retails for $45.
|
|
|
|
|
I wrote a COM Server using ATL wizard, so i made a DLL, and want to use it on another machine - but, when i try to register my server using regsvr32 i have next message:
"LoadLibrary("the way to my dll") failed. The specified module could not be found".
Where the problem is???
|
|
|
|
|
Simply it tries to say, that some library your dll depends on is missing. I would suspect, that you built your dll with dependency on msvcrt libraries that are supplied with VC.
You can either redistribute the dlls or you can build it with no dependency using static linking - see project settings of your project.
Anyway, you can check the dependency with the depends tool from the SDK.
|
|
|
|
|
Yes, i built my programm with static linking method. And i noticed one thing, if Visual Studio and Active Sync installed on machine, my dll registers successfully, but if one of theme is apsent it writes an error. I tried to use dependecy utility, found all the dlls and copied them with my COM dll on another machine, and still have error.
|
|
|
|
|
Well, simply, if the LoadLibrary function in the regsvr utility failed, there's still something missing - did you copied all the dlls your library depends on into the same path, or somewhere where it can be found by LoadLibrary ?
Or possibly, there can be dll missing that is required by some of the dlls you are depending on.
By static linking in VC I mean what you find in Project properties , C++/Code Generation and Runtime Library setting.
Here should be /MT or /ML .
|
|
|
|
|
Thanks!
I've been having the same problem and it's been driving me
nuts for a week. I could not figure out what was going on.
My new dll made use of other dll's, and I didn't have them
in the path.
|
|
|
|
|
Hi,
This following code in a console application:
CoInitialize(0);
HRESULT hr;
SHDocVw::IShellWindowsPtr spSHWinds;
hr = spSHWinds.CreateInstance (__uuidof(SHDocVw::ShellWindows));
====> Returns 0x0x80040154 - Class not registered.
Can someone please help me why I am getting this error?
Any help would be greatly appreciated.
SenPy
|
|
|
|
|
hm. try to specify as argument ProgId. smth like, "SHDocVw.SHDocVw" or "{A21A4187-5A86-4E26-B40A-856F9035D93B}" - clsid of your component.
4apai
There're no impossible tasks. There're tasks that required infinite period of execution time.
|
|
|
|
|
I have an ActiveX control which displays models containing a huge number of facets in OpenGL. I use recursion during the building of the models and unfortunately am overflowing the stack.
How does one increase the size of the stack in a COM/ATL dll?
I've tried the compiler option '/F' and linker option '/STACK' without any luck. Is there a way to do this programmatically?
Thanks in advance!
Emil
|
|
|
|
|
As far as i recall, the stack size is not related to a DLL, its the process including the DLL that is deciding on its stack size.
Depending on the amount of information stored on the stack, it would probably be better if you kept only a pointer to a struct with the info you need at each level of recursion. You could event count the recursion level and keep some information into an array that is dependant on the recursion level.
Here are a few points you might want to investigate too.
How many levels deeps are you getting into ?
Are you sure you're not simply entering an infinite recursion which does overflow the stack.
Is the recursive function having too many parameters, could you simplify these parameters and pass in a struct pointer ?
Are there too many local variables in my recursive function ?
Every time you enter a function, there is a number of bytes being reserved in the stack, each parameter passed to a function could be taking some stack space so if you recurse on a function that requires 40 bytes for its parameters it can add up quickly. Also, local variables do take space on the stack.
Having a recursive function with "char somearray[512]" isnt convenient in a recursive function since on each recursion level, 512 bytes will be reserved for that level.
|
|
|
|
|
Hello I'm new to COM and ATL. I need some help regarding add-ins. I want to make an add-in for the Visual Basic Editor, displayed as a dialog-style window, using Visual C++. I know that COM and ATL are used, but I have no idea how to start.
Also, the displayed dialog needs to keep track of the currently selected item (i.e. a Form, or a control within a Form) and read it's properties (color, text, etc.).
I have looked over the articles discussing add-ins, but they don't address my situation. Any help would be greatly appreciated.
Thanks.
|
|
|
|
|
Hi,
Here is the part of the EXE code:
if (FAILED (CoInitialize (NULL)))
{
return FALSE;
}
...
...
HRESULT hr;
IWebBrowser2* pWebBrowser = NULL;
hr = CoCreateInstance (CLSID_InternetExplorer, NULL,
CLSCTX_LOCAL_SERVER, IID_IWebBrowser2,
(LPVOID*)&pWebBrowser);
====> hr is 0x80070005 - Access is denied.
This is happening only with Windows XP/SP2. On the same PC with SP1, it works fine also it works fine on W2K.
Can someone PLEASE help me to solve this issue?
Thanks
SenPy
|
|
|
|
|
Maybe you now need to CoInitializeSecurity() ?
XP2 now has a more secure web browser system and this is a good thing.
|
|
|
|
|
|
Hi
I have handle to window to activeX control i want to get Idispatch of
this control in other thread. I use following code in same thread to
get interface pointer but when i call same function in other thread
it does not work
void fn(HWND *h)
{
::CoInitialize(NULL);
CWnd *c=CWnd::FromHandle(h1);
LPUNKNOWN pUnk =c->GetControlUnknown();
::wsprintf(a,"%p",pUnk);
::AfxMessageBox(a,0,0);
if(pUnk)
{
LPDISPATCH pDisp=NULL;
pUnk->QueryInterface(IID_IDispatch, (LPVOID*)&pDisp);
//doing some function with idispatch
}
}
this function works fine in one thread but in other thread it return
Iunknown pointer NULL. If any body knows solution plz reply me as
soon as possible. Remember i am not working with control that
register themselves i mn working with MSFlexGrid control.
Thanx in advance
Danish Ali
|
|
|
|
|
in one thread all is fine because u are in one apartament. to access interface in another thread i use COM marshaling. CoMarshalInterThreadInterfaceInStream<->CoGetInterfaceAndReleaseStream functions or GIT table.
but i didn't use it on remote threads. hm. maybe this is the part of sollution.
4apai
There're no impossible tasks. There're tasks that required infinite period of execution time.
|
|
|
|
|