|
I have an ATL/MFC COM DLL which a customer is trying to use from Delphi 6 Enterprise SP2. He was having trouble setting properties, and eventually discovered that all of the Set_* procedures in the auto-generated TLB file are empty. The only ones that aren't empty are for BSTR properties.
We have no problems using the DLL from C++, VB or ASP.
Has anybody experienced something like this? Am i missing a MIDL keyword? Is it a build/linker setting? Do I need to specify something in my .DEF file? Or is Delphi to blame?
---
Here's how things are defined in my project:
// from my .idl file
[propput, helpstring ("blah"), id(6)] HRESULT RepeatCount([in] long newVal);
// from the corresponding .h file
STDMETHOD(put_RepeatCount)(/*[in]*/ long newVal);
// from the corresponding .cpp file
STDMETHODIMP CMyClass::put_RepeatCount(long newVal)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState())
m_lRepeatCount = newVal;
return S_OK;
}
// from Delphi's auto-generated MyDLL_TLB.BAS
procedure TMyClass.Set_RepeatCount(pVal: Integer);
begin
Exit;
end;
---
Thanks,
Gary
|
|
|
|
|
Hi guys.
I have an out-of-process COM server, which has numerous clients connecting and disconnecting to/from it. Server must know about every client instance connected to the it. The problem is, that when a client is abnormally terminated server has NO way to determine that the client is not there anymore, and this situation is very unhealthy. Does anyone know how to solve this problem?
|
|
|
|
|
sergeyv2002 wrote:
Does anyone know how to solve this problem?
There's many ways to this out-of-band. For instance with "pings" using TCP, pipes, shared memory, etc. I am not sure if there are any other methods in pure COM. Maybe there are in COM+, but that doesn't help you much I imagine.
Out-of-band is the only way to go that I can think of.
--
Weiter, weiter, ins verderben.
Wir müssen leben bis wir sterben.
I blog too now[^]
|
|
|
|
|
Hmm.. wait. There's another way that might work. Each time a client connects, require them to pass an IPingable* reference to themselves. Then call IPingable::Ping() regularly to see if the client is still alive. I believe you'd get an RPC_E_XXX error message back when the connection has been severed.
However, this would require circular references, so you'd need to setup up some termination protocol so that both server and client will release eachother.
--
Weiter, weiter, ins verderben.
Wir müssen leben bis wir sterben.
I blog too now[^]
|
|
|
|
|
Hello Jorgen,
I think the IPingable interface is a good idea. I too have a need for such an infrastructure for my EXE COM server to check the "live" status of its clients.
Thanks for sharing the idea.
Best Regards,
Bio.
|
|
|
|
|
Thanks Jörgen. I will try your approach.
Thanks again.
|
|
|
|
|
Please let me know if it works out. I might have to solve a similar problem in the near future.
--
Weiter, weiter, ins verderben.
Wir müssen leben bis wir sterben.
I blog too now[^]
|
|
|
|
|
Hello sergeyv2002, Jorgen,
Have you considered using the DCOM architecture ? I read somewhere that DCOM uses the ping mechanism as described by Jorgen.
The other idea is to use .NET Remoting which uses something known as leasing. Leasing basically caters to remote object lifetime management.
Just some ideas to share.
Regards,
Bio.
|
|
|
|
|
Lim Bio Liong wrote:
Have you considered using the DCOM architecture ?
Yes, but it's a bit overkill for a desktop app which is not distributed in nature. At least not distributed over the network. I just want other apps to automate certain tasks.
Lim Bio Liong wrote:
The other idea is to use .NET Remoting which uses something known as leasing
.NET is not an option for me.
--
Weiter, weiter, ins verderben.
Wir müssen leben bis wir sterben.
I blog too now[^]
|
|
|
|
|
Hi,
for some resons i try to implement some functions to load COM dlls without accessing the registry.
I don't know what dlls to load because the user of the application may add/remove dlls (they are used as plugins).
The only thing i know is the (relative) path of the directory that contains the dlls.
My idea is, to search this path, load the dlls into memory (LoadLibrary()) and initialize them using the functions
GetProcAdress() and DllGetClassObject(). ( -> these steps should be the manual implemantation of CoGetClassObject()- function ?! )
The only problem (so far... ) is, how to estimate the CLSID i need for the initialization?
(In my old registry based implementation i estimated them from the registry using EnumClassesOfCategories())
Currently i assume, a viable but not nice solution is to implement a "GetMyCLSID()" - function in the dlls.
Does anyone knows a better solution for this, does there exists a function to estimate the CLSID from a dll (BEFORE it is accessible as COM object)?
Has anyone some experience with this or a similiar solution or another solution for this problem?
Thanks in advance
alcedo
|
|
|
|
|
Hie,
I think u can do it using ITypeLibrary Interface. Just search MSDN with this interface, U can enumerate all the details inside tlb file and I think COM dlls will also work. If not make tlb from DLL and go ahead.
|
|
|
|
|
Howdy -
I have a fully qualified PIDL (i.e. LPITEMIDLIST struct), and I am completely at a loss as to how to get the parent (full qualified) PIDL from it?
Any thoughts?
Marcus Spitzmiller
"Why must life be so hard? Why must I fail at every attempt at masonry?" - Homer
|
|
|
|
|
Hello,
I am devloping COM server in C++
I am new to COM and I have a basic question on kind of parameters that a COM method can accept.
(
can we pass STL's ?
can we pass by reference ?
can we pass user defined objects ?
)
I intened to call this C++ COM from a cleint developed in VB.
For example , is it possible to add the following method to the COM server to be called from VB client
void test(std::vector
|
|
|
|
|
Hello PeKu,
All parameters of COM Object methods must be marshallable across
process and even machine boundaries. This is why when we define COM
interface method parameters (in an IDL file), we have to specify whether they are [in] or [out] parameters.
When we want to use our own user-defined structs as parameters, we must also
specify the attributes to the individual fields of these structs ([in],
[out] are amone these attributes). This is done in the IDL file of your
project.
These attributes help the MIDL compiler to produce marshalling code that will be used when the parameters of your COM methods are transported from one thread to another and from one process to another and even from one machine to another.
I will now attempt to answer your questions point by point. Please note that my answer is generic and will not apply to your VB client case. Take good note of this but I will address your VB client question later.
>> can we pass STL's ?
I believe that it is technically possible to define the marshalling
attributes of STL classes (e.g. vectors) but I doubt if it will be
simple. Remember that the most important thing about COM method parameters is that the MIDL compiler be able to produce the appropriate marshalling code for them.
>> can we pass by reference ?
If C++ referencing is what you mean, I don't think this is possible. But if you mean "pointer to pointer", yes, this is certainly possible (use the [in, out] attributes.
>> can we pass user defined objects ?
If your user-defined objects are in the form of structs, yes, but you need to define attributes for the individual fields of your struct.
If your user-defined objects are represented in the form of interface pointers, yes, this is certainly possible.
Let me now move on to your VB client case...
>> I intened to call this C++ COM from a cleint developed in VB.
In this case, the above points will not work. If your client is VB-based, then your COM objects MUST BE DUAL-INTERFACED. This means that the parameters to your COM methods MUST be one of a finite set of pre-defined types. These include long, int, BOOLEAN, and, of course the VARIANT. These types are also known as AUTOMATION-compatible types.
Take note, however, that the VARIANT type is a union that encompasses most of the popularly used types so you will usually be fine using it.
>> void test(std::vector
It will not be possible to define a parameter of this type. The only way to define an array type of parameter and to use it in relation to a VB client is to use the SAFEARRAY.
Hope the above helps, PeKu.
Regards,
Bio.
|
|
|
|
|
all i have is a com idl file, and i need to basically implement the component the idl file describes. what steps do i need to take? for example, should i create a new atl project, insert a new object with the names matching the ones in the idl, build the project, and then finally implement the actual component?
|
|
|
|
|
Yeah, that sounds right. You're not going to use the same GUID, are you ?
Christian
I have several lifelong friends that are New Yorkers but I have always gravitated toward the weirdo's. - Richard Stringer
|
|
|
|
|
why? do i need to change the idl file?
|
|
|
|
|
Reusing the GUID would break every principle of COM. Either way, what you're doing sounds like a bad idea to me, but that would make it far worse. You really should rename the component as well, but if you do all that, there's no point basing it on an existing IDL file.
Christian
I have several lifelong friends that are New Yorkers but I have always gravitated toward the weirdo's. - Richard Stringer
|
|
|
|
|
hmm, i think you are misunderstandign what i am doing. i have an idl file, not from an existing com component, but from one that has yet to be created. in other words, this component hasn't even been implemented yet. the idl file was created first, and given to me so i can develop code to exercise the com component WHEN it actually is implemented. so in other words, i implement the com component myself, write the code to exercise it, and then when the "real" component is done, my exercising code will work with it.
does that make sense?
thanks
|
|
|
|
|
yeah you have create a ATL project.
if you don't Mind, itell you some step.
use that IDL File as help.
--->First Create a Atl Project
--->then Add Atl object as Written in IDL file.
----> add MEthod and Property accodinly
if problem still persist,you can mail me your idl file ,i will make a dummy atl project for you. my mail address is alok@efextra.com
-----------------------------
"I Think It Will Help"
-----------------------------
Alok Gupta
visit me at http://www.thisisalok.tk
|
|
|
|
|
Hi,
I think following steps may help u.
1) Create new ATL project.add your IDL file to it.remove or overwrite the original one.
2) Now class/components you have to create your own, add these classes needs to have same declaration as of com classes
3) then right click on these classes and say implement interface . It will add all functions listed in the IDL file.
these are not standard steps.Just it helps you out.
|
|
|
|
|
How to get the frame rate of a .wmv file while the IWMInfoHeader interface cannot get the related attributes? Thanks
|
|
|
|
|
During the work i have provided the task for Creating the
#1 evaluation version Component or ActiveX Dll
#2 Developer Version DLL
#3 Runtime DLL.
i have almost sorted out First task By producing a Modeless Atl dialog box .
but i still can't understand how to develop Developer DLL and Runtime Dll ,as i was told that you have to stop runtime dll to connect to IDEso that only application can use that.
can any body provide me any good pointer towards it.
-----------------------------
"I Think It Will Help"
-----------------------------
Alok Gupta
visit me at http://www.thisisalok.tk
|
|
|
|
|
Hi Alok,
1. For the Runtime DLL, you need to stop the DLL from running under a debugger/IDE.
Have a look in the MSDN documentation for ::IsDebuggerPresent()
Also look at ::GetModuleFileName() - check the value that comes back and see if it corresponds to known debuggers/IDEs (eg "DEVENV", "MSDEV", "WinDBG") etc.
Of course, some sneaky people might rename MSDEV.EXE to something else. In this case you could go here[^] and grab the CVersionInfo class. Initialize it with the path returned from GetModuleFileName() and do the same check for known debuggers/IDEs using the value returned by CVersionInfo.GetInternalName(). Unless they go to the effort of changing the values in the Version Block, this will work.
You also want to see what the parent process is. Have a look at KB article 175030, which will show you how to do this. Again, once you have the name of the parent process you can do the debugger/IDE name check as above. This means that even if someone executes your DLL using Ctrl+F5 from Visual Studio (which "detaches" the executed program from the debugger) it will still trap them.
2. For the Developer DLL you don't need to do anything. I suppose if you *only* want it to run under a debugger/IDE, then you can just use step (1) and reverse all the logic
Of course none of this is foolproof, but it will slow people down. I've used these methods and they work well.
Hope this helps,
Gary
|
|
|
|
|
Thanks Sir.
Sir Garence wrote:
Of course none of this is foolproof, but it will slow people down. I've used these methods and they work well.
Atleast something is better then nothing
-----------------------------
"I Think It Will Help"
-----------------------------
Alok Gupta
visit me at http://www.thisisalok.tk
|
|
|
|