|
IDL does not support namespaces, which are a C++ thing. IDL is designed to be language neutral. When you #import a type library, the namespace is generated by the C++ tool doing the import, not the type library.
Steve S
Developer for hire
|
|
|
|
|
Steve S wrote: When you #import a type library, the namespace is generated by the C++ tool doing the import, not the type library.
But how does the C++ tool (MSVC) knows which namespace to use if I #import "MSXML*.dll"? That info must be in the dll?
|
|
|
|
|
Because it uses the library name, which is in the IDL as
library MSXML2
{
// TLib : // TLib : OLE Automation : {00020430-0000-0000-C000-000000000046}
importlib("STDOLE2.TLB");
....
Steve S
Developer for hire
|
|
|
|
|
Hi,
I'm a beginner in COM, and have a question in my program need your help~
I use either _beginthreadex or CreateThread to create a thread in my COM dll's DLLMain function's
case DLL_PROCESS_ATTACH:
the thread will run a while loop to excute ReadDirectoryChanges for real time monitor directory,
but very wired, the whole COM dll will hang by that thread, other function in the dll can't work, because
whole dll is hang in there when excute ReadDirectoryChanges.
when I take off ReadDirectoryChanges from Com dll, use a individual simple project create a thread
run ReadDirectoryChanges is OK, but when COM dll combine with create thread run ReadDirectoryChanges,
the COM dll will hang there, so it maybe the COM thread setting problem? or any other issue?
Please help me~ Thanks~
|
|
|
|
|
You can create a thread in DllMain, but you can't wait on it. It will immediately cause the OS to try to re-enter DllMain to give the DLL_THREAD_ATTACH notification, but the new thread will wait there because it needs to acquire the Loader Lock. Your original thread will already have the Loader Lock, and will not release it until it returns from DllMain. If the first thread now tries to wait for some other event to occur that's signalled by the second thread, you have a deadlock.
Basically, don't do any work at all in DllMain. Instead, do lazy initialisation, when actually needed. In a COM object you might do this in the object's constructor, or otherwise in response to CoCreateInstance. For example, ATL offers the FinalConstruct method to allow you to do extra initialisation after the constructor has run but before CoCreateInstance returns.
Finally recall that interface pointers are apartment-relative. If calling back into a client from a worker thread, you need to make sure the call is marshalled correctly. See the Global Interface Table for an idea of how to do this.
|
|
|
|
|
|
BY THE NAME OF ALLAH ,
i am asking for any new Idea for my graduation project , iam in computer science dep. i want in any field so plz any One know
tell me . i will be thankful .
thnkx , amal emam
|
|
|
|
|
I am having some difficulty in my C++ app with memory management. Currently the client app sets up a struct **pPointer that is passed to the COM+ method on the server. The server then reads a database and creates a record set. This record set is processed and the server then CoTaskMemAlloc’s space for each of the processed records. The array of pointers is then passed back to the client.
The pointers all seem to be marshaled fine. The data is processed, and then I CoTaskMemFree the pointers, and release the Access Object to decrement the object reference count. Even though the object seems to have no more references to it (ie the object is no longer spinning in Component Services), the server (dllhost.exe) is still holding on to the memory that was allocated on the server. After about 30 minutes the memory is eventually free’d. However the memory use is very large and multiple clients are utilizing the system. It does not take long to run out of resources and the server crashes with a ‘COM Surrogate error’ . My guess is that when the server runs out of memory, it errors and returns a NULL pointer. As Windows is trying to marshal the null pointer, the error situation occurs (but this is just a guess, it could be a bad uninitialized pointer).
I need to figure out how to free the memory on the COM server after I am done with it, so that it can be released. Any help would be greatly appreciated.
Client Side Code Snippit:
<br />
hr = CoCreateInstance( CLSID_ValuesAccessObject,<br />
0,<br />
CLSCTX_ALL,<br />
IID_IValuesAccessObject,<br />
(void**)&m_pidsrtval );<br />
<br />
...<other processing>...<br />
<br />
hr = m_pidsrtval->GetAllValues( GetDbConnectionString(),<br />
&nValues,<br />
&pspdcrtbv );<br />
<br />
<br />
...<other processing>...<br />
<br />
for( int i=0; i<nValues; i++ )<br />
{<br />
SPDCRTBV *paspdcrtbv = &((*ppsptbvValues)[i]);<br />
<br />
CoTaskMemFree(paspdcrtbv->pdvQualifiers);<br />
paspdcrtbv->pdvQualifiers = NULL;<br />
<br />
CoTaskMemFree(paspdcrtbv->pdvFacts);<br />
paspdcrtbv->pdvFacts = NULL;<br />
<br />
}<br />
<br />
CoTaskMemFree(pspdcrtbv);<br />
m_pidsrtval->Release(); <br />
Chris
|
|
|
|
|
hi everyone,
i created a activex control(.ocx),and placed the same in the form for testing,after placing not able to move(drag) the control to other places in the form
pls let me know whats missing on my control,
thanks n advance
rahul
rahul
|
|
|
|
|
Hi,
I have to build a layer of serviced components over a DAL (data access layer). Now this DAL was written using interop in VC++.
I built my component using a snk - which worked fine till i added the code to access DAL. Now it gives me an error sayin that assemly cannot be created as DAL does not have a strong name.
How do I get rid of this problem? How can i reuse the existing component without having to rewrite it in .net environment?
I recently read an article sayin that i would have to generate a strong key for the interop dll using tlbimp... but i somehow am not able to figure the parameters out ... has anybody done this?
Any help will be appreciated!
|
|
|
|
|
You only have to generate a strong name for interop if you plan to put the class library assembly into the GAC. This is recommended if you're going to share the component between applications, for example have multiple applications install the same component, but isn't actually required. The regasm utility can be made to register a class library DLL in any location using the /codebase switch; the Visual Studio deployment project's Register property, if set to 'vsdraCOM', will set the Codebase registry value appropriately if you're not installing the assembly to the GAC.
If you do install the same assembly from two different locations, then uninstall one of them, the registration will be broken for the other one. That's why the GAC is recommended.
If you do want to use the GAC, all assemblies that this one depends on will need to be signed and installed to the GAC as well. You can sign the DAL using the C++ linker's /KEYFILE option; you must specify this option in the 'Additional Options' field in the Linker options.
|
|
|
|
|
Hi,
How to register XPCOM component using XPInstall?
Thank you.
Ayesha
|
|
|
|
|
|
which book is good for COM
|
|
|
|
|
|
Essential COM (Don Box) - it goes into a lot of depth and can be quite daunting in places but it's a goldmine of important information.
|
|
|
|
|
|
Hi!
I am a newer.,
What is COM?
Why we relates this one to .net..?
If i want to know basics abt the COM Can you refer any good site..?
T.Prabu
|
|
|
|
|
search in msdn site good one
|
|
|
|
|
|
Hello friends,
For the first time I am working with ActiveX control.I have search
through net but not getting the clear idea how t handle events in
active x.
I have dialog based application and i have added a contol in that
through project ->add to project
components and control. and then add arielapi control by which i got a
wrapper class ,.cpp file, and .h. file.
THIS ARE CLASS METHOD in arielapi.cpp
<br />
CString CArielAPI::Login(LPCTSTR UserName, LPCTSTR Password, LPCTSTR<br />
UserId)<br />
{<br />
CString result;<br />
static BYTE parms[] =<br />
VTS_BSTR VTS_BSTR VTS_BSTR;<br />
InvokeHelper(0x2, DISPATCH_METHOD, VT_BSTR, (void*)&result, parms,<br />
UserName, Password, UserId);<br />
}<br />
<br />
CString CArielAPI::RequestPrices(LPCTSTR SessionId, short PageNumber)<br />
{<br />
CString result;<br />
static BYTE parms[] =<br />
VTS_BSTR VTS_I2;<br />
InvokeHelper(0x3, DISPATCH_METHOD, VT_BSTR, (void*)&result, parms,<br />
SessionId, PageNumber);<br />
return result;<br />
}<br />
<br />
<br />
CString CArielAPI::RequestDeal(LPCTSTR SessionId, long MarketNo,<br />
LPCTSTR Amount, short TradeType, LPCTSTR Exchange, short BuySell,<br />
LPCTSTR Account, LPCTSTR ClientRef)<br />
{<br />
CString result;<br />
static BYTE parms[] =<br />
VTS_BSTR VTS_I4 VTS_BSTR VTS_I2 VTS_BSTR VTS_I2 VTS_BSTR VTS_BSTR;<br />
InvokeHelper(0x4, DISPATCH_METHOD, VT_BSTR, (void*)&result, parms,<br />
SessionId, MarketNo, Amount, TradeType, Exchange, BuySell, Account,<br />
ClientRef);<br />
return result;<br />
}<br />
<br />
CString CArielAPI::RequestQuote(LPCTSTR SessionId, long MarketNo,<br />
LPCTSTR Amount, short TradeType, LPCTSTR Exchange, LPCTSTR Account,<br />
LPCTSTR ClientRef)<br />
{<br />
CString result;<br />
static BYTE parms[] =<br />
VTS_BSTR VTS_I4 VTS_BSTR VTS_I2 VTS_BSTR VTS_BSTR VTS_BSTR;<br />
InvokeHelper(0x5, DISPATCH_METHOD, VT_BSTR, (void*)&result, parms,<br />
SessionId, MarketNo, Amount, TradeType, Exchange, Account,<br />
ClientRef);<br />
return result;<br />
}<br />
<br />
AND this are events method which are getting by right clicking the
control in dialog box.
<br />
void CWartz_newDlg::OnLoginArielapictrl1(LPCTSTR SessionId, short<br />
Accepted, LPCTSTR FailureMessage)<br />
{<br />
<br />
<br />
}<br />
<br />
void CWartz_newDlg::OnPriceQuoteArielapictrl1(LPCTSTR SessionId,<br />
LPCTSTR RequestId, LPCTSTR Price, short Timeout)<br />
{<br />
<br />
}<br />
<br />
i want that when i click button it get connected to server and if
successful and get sessionid start getting the price qoute.and display
it and i dont know what to do with events if i want to fire events what
should i do for that Can anybody help me to solve this problem..
for connection button the code is :
<br />
<br />
void CWartz_newDlg::OnConnect()<br />
{<br />
CString sessionid= m_arielapi.Login("wwtest2","RD9234","wwtest2");<br />
CString serveradd=m_arielapi.GetServerAddress(sessionid);<br />
<br />
<br />
CString cstrDisplayData;<br />
cstrDisplayData.Format(_T("==>Connected to<br />
server[%s][%s]"),serveradd,sessionid);<br />
LOG(0,cstrDisplayData);<br />
}<br />
<br />
-- modified at 2:05 Wednesday 23rd August, 2006
|
|
|
|
|
We can call activex function with object of activex control. The OnConnect function will be called like this
obj.Connect
or
You can write connect code in button click event
Thanks & Regards
Kumar
abc
|
|
|
|
|
I have a atl control, having two properties. I want to use the html tag "param" to set new value. How? Thanks.
|
|
|
|
|
Hi,
I have a problem with a C++ COM server which is a service.
I define my own data structure with a bstrName and an integer for example.
And I try to get a list of the structure with a VB Client.
Here is the code of my COM object :
<br />
class ATL_NO_VTABLE CGWCServerLorCom : <br />
public CComObjectRootEx<CComSingleThreadModel>,<br />
public CComCoClass<CGWCServerLorCom, &CLSID_GWCServerLorCom>,<br />
public IGWCServerLorCom<br />
{<br />
public:<br />
CGWCServerLorCom();<br />
~CGWCServerLorCom();<br />
<br />
DECLARE_REGISTRY_RESOURCEID(IDR_GWCSERVERLORCOM)<br />
<br />
DECLARE_PROTECT_FINAL_CONSTRUCT()<br />
<br />
BEGIN_COM_MAP(CGWCServerLorCom)<br />
COM_INTERFACE_ENTRY(IGWCServerLorCom)<br />
END_COM_MAP()<br />
<br />
DECLARE_CLASSFACTORY_SINGLETON(CGWCServerLorCom)<br />
<br />
public:<br />
STDMETHOD(GetTagSpy)(long lgTagSpy, long *plgTagSpyReal, GWC_TAG_SPY_INFOS *pTagSpyInfos);<br />
lgTagSpy = size of the list given
plgTagSpyReal = real size of the list
pTagSpyInfos = list of structures
The structure is defined like this :
<br />
typedef struct ST_GWC_TAG_SPY_INFOS<br />
{<br />
BSTR bstrTagName;<br />
BSTR bstrTagValue;<br />
LONG lgTagValue;<br />
} GWC_TAG_SPY_INFOS;<br />
Actually I have 2 problems nowdays.
in VB I defined a table m_tabTagSpy() as GWC_TAG_SPY_INFOS
Let say I want 10 Tags : redim m_tabTagSpy(10)
I call m_pIServerLorCom.GetTagSpy 10, lgRealSize, m_tabTagSpy(0)
In return I only have the first value filled, when I check in debug, the C++ fill the all structure whithout exception, but returning the hand to the VB and every datas are lost !!!
Moreover if I ask the values one by one, I have big memory leaks but I don't know where.
If anyone could help I would be very grateful.
Matt.
|
|
|
|
|
Since you're working with VB, you're best off with an Automation-compatible interface. I would recommend using a SAFEARRAY of your structure.
Your problem is stemming from the Automation marshaller not knowing that you actually want an array; it therefore does not marshal the data appropriately across the process boundary.
See this article[^] for information on how to use arrays of user-defined types in COM objects.
|
|
|
|
|