|
Gary,
Try importing the Type library (using importlib("..")) of the enum idl into the type library definition of your components idl and not anywhere else. This might work.
for eg.. consider ur enum idl as "SampleEnum.idl" and its tlb as "SampleEnum.tlb"... then your component idl shud be like,
#import "SampleEnum.idl"
[...]
interface Izzzzzz : Ixxxxx
{
}
[...]
library xxxxx
{
importlib("SampleEnum.tlb");
// your coclass definition goes here
}
Hariharan.T
|
|
|
|
|
Hi Gurus,
I have to call a function in VB COM, with parameter SAFEARRAY ** (it's originally "ByRef TabList() As String" in VB), as below:
HRESULT bGetTab(SAFEARRAY ** TabList, long* iMaxNumber).
I successfully called it with Smart Pointer without any problem (but seems Smart Pointer is doing early binding, I guess it might not be compatible with the next version of that VB COM).
So, I tried the InvokeHelper to do late binding. It's working with the simple functions generates by ClassWizard, but not with that bGetTab function. Here is my code for InvokeHelper (I have to make it by myself, cause the ClassWizard is not capable to generate for that function)
// Function to get a string table with iMaxNumber elements
// VB Code: Public Function bGetTab(ByRef TabList() As String, ByRef iMaxNumber As Long) As Boolean
BOOL CKMServices::bGetTab(SAFEARRAY **TabList, long *iMaxNumber)
{
BOOL result;
static BYTE parms[] =
VTS_PVARIANT VTS_PI4;
InvokeHelper(GetDispid(this->m_lpDispatch, _T("bGetTab")), DISPATCH_METHOD, VT_BOOL, (void*)&result, parms, TabList, iMaxNumber);
return result;
}
// And how do I call that function
SAFEARRAY *arrTab = NULL;
arrTab = SafeArrayCreateVector(VT_BSTR, 0, iMaxNumber);
if (!arrTab) _com_issue_error(E_OUTOFMEMORY);
if(!m_KMServer->bGetTab(&arrTab, &iMaxNumber))
{// Return custom error message }
I've allocated my TabList before calling. But I'm not sure what the type to put for SAFEARRAY **. I have tried VTS_PBSTR, with the same result (it raised COleException).
Thanks before,
Hany
|
|
|
|
|
Hi all!
I tried to post this in the C# forum, but without replies. I tought I might try here too.
I have a small Interop question:
I have a COM object that takes a structure as in-parameter. One of the fields in the structure is an IID*. When doing this in C++ the code:
GUID rrid = __uuidof( _InterfaceName );
parStruct.riid = &rrid;
works fine.
How would I do this in C#? I have tried several things, but can´t get it to work. The type of the struct-field in C# is intPtr. And the only way I can find such a type, that I can think of, is:
Type t = typeof( _InterfaceName );
System.RuntimeTypeHandle h = t.TypeHandle;
parStruct.riid = h.Value;
But I guess that I am way off here.
Any one that can give me a hand here?
Regards
Mikke
Added info:
Hi again!
I tried to create a C++ .Net project instead, just to try and find a work-around. When I took the COM objects needed and tried to import them into my brand new cpp project i got this error message:
TlbImp warning: The type library importer could not convert the signature for the member 'RobEventParams.riid'.
And a couple of other ones like this one for other similar parameter-structs with riid fields. What does that mean for me? Is it impossible to marshal something from .Net into this COM? The purpose is to set up a sink and recieve events from the COM object, to do this I should send a ref to an object that should recieve the events and the signature of an interface implemented in the receiver. It is the interface "signature" that is the riid, and also the problem here. When I execute my C# code above I get an exception telling me that "No such interface supported". Do I have to submit a non-.net method as a sink here?
Best regards again / Mikke
|
|
|
|
|
I can see why no one responded to your inquiry. The way you phrased it is confusing, even to me, and I read it and then re-read it several times.
The basic concept is that you are trying to write a .NET application that will respond to events fired from a COM object that you have imported.
While it appears that this should be a simple matter, it is actually confusing as hell. I have a copy of the book, ".NET and COM: The Complete Interoperability Guide", by Adam Nathan, that I have learned an immense amount of 'stuff' from. I would highly recommend it, especially if you do this type of thing alot. He has an entire chapter devoted to the subject, "Responding to COM Events", which is about 50 pages long and describes the techniques clearly and in detail.
To be perfectly honest with you, I don't completely understand the matter, and I am reluctant to provide you with confusing information.
However, you are working in the right direction. In his book, Adam Nathan describes the callback mechanisms for both .NET and COM, and, while similar, they differ significantly. Basically, he describes the way the type library importer transforms the Source Interface in order to expose the COM object connection points as .NET events using a number of additional types (these are: an event interface, a delegate, a private class that handles interaction with the connection point, and a private sink class that implements the source interface).
It is just too much information to adequately describe here. I suggest that you consult his book.
|
|
|
|
|
Hi Folks )
i've got a strange problem with BSTRs in my DCOM application.
I'm passing 6 BSTRs in a class object (its properties) to a method on a remote server that has to write these strings in some registry values on a pre-defined key.
I've tried both allocating a BSTR and passing it to the server function (see next few lines
BSTR bsBuffer;
bsBuffer=SysAllocString(OLESTR("Prova"));
theApp.m_pHello->SetName(bsBuffer);
SysFreeString(bsBuffer);
and calling server functions directly passing a string (confiding in the operator= that BSTR involves).
theApp.m_pHello->SetDescription("Prova 02/05/2005");
theApp.m_pHello->SetDriver("0.01a");
theApp.m_pHello->SetName("Prova");
theApp.m_pHello->SetVendor("Execute, Crash & Sigh LTD");
theApp.m_pHello->SetLocalBus("VXI");
theApp.m_pHello->SetFirmware("0.00001a");
//Adding Object
theApp.m_pHello->Add();
Running application there is no errors, no code violations, no abnormal program terminations, NOTHING....
BUT
In the registry I get a strange thing like this (I report values in tabular format)
sDesc=Execute, Crash & Sigh LTD
sDriver=0.00001a
sFirmware=0.00001a
sLocalBus=0.00001a
sName=0.00001a
sVendor=Execute, Crash & Sigh LTD
All server functions do nothing but extract the string part in the BSTR and save it in the registry using Windows API functions.
What can I do?
What can it be?
Thanks a lot in advance,
Moreno.
|
|
|
|
|
Try the first one an don't free the Memory (SysFreeString)
Best now?
|
|
|
|
|
OK, I will not free the memory soon, but WHEN can I free that memory?
I don't want to make a memory-consuming server...
Thanx again....
|
|
|
|
|
Marshaling layer in COM do free for you in the client side if parameter is [in] type and in server side in [out] parameter. You must free memory (SysfreeString) in client side for [out] parameter,...
Try to use _bstr_t type and forget memory alloc and free.
Regards...
|
|
|
|
|
OK, I tried to follow your tip and went into trouble again (i'm not SO experienced ).
Most of my server Interface's methods use the BSTR type. I tried to change it, but now I need to know how to declare the _bstr_t type in my IDL file. I tried using both import and include (with and without #) WTYPES.H (where _bstr_t is defined) and it seemed not to work (preprocessor error). How to declare it?
Another STRAAAAANGE thing is that it fails calling methods that has three int parameters... I know that native C types do not need to be marsaled, am I right?
i.e.:
theApp.m_pIHello->SetLocation (2,1,0)
seems to fail, where function prototype in server side is
STDMETHODTYPE CHardwareAsset::SetLocation (int Master, int slot, int SubAssy)
I put a statement to log on a file somw phrases just to know where the program goes and what it does, but when I call the method above, the server creates the object, but does NOT log the SetLocation Fu8nction (the logFile statement is the first, just before variable declaration!)
Very strange, isn't it? Or it's me that need to return to school and study a lot?
Thanks again...
|
|
|
|
|
Looks like the theApp.m_pHello object doesn't rightly store the transmitted BSTR strings inside.
BSTR strings should be stored by copying of the body, not the pointer.
HRESULT C::SetName(IN BSTR name) <br />
{<br />
m_nameSaved = name;
}<br />
<br />
HRESULT C::Add()<br />
{<br />
}
With best wishes,
Vita
|
|
|
|
|
OK, and that's what I did, but now that I think, I should do the same thing not only on client side, but also on server side....
I'll give it a shot, and I'll report how things went....
Thanks again...
|
|
|
|
|
I've been successfully using the MS Excel 9.0 object library for some time now to perform simple tasks manipulating excel. However I now only have the version 10.0 library available. I assumed there would be backwards compatibility but I am having issues. When refreing to cell contents I used to use .value but this seems to have disapeared in version 10 which only seems to have .value2???
Has anyone seen this issue before?
|
|
|
|
|
Hi,
I am writing an application which will work as client as Microsoft Netmeeting 3.0 using the interfaces exposed by NetMeeting SDK.
I have created a conference and hosted that. When i am getting the Sharable Application list through IEnumNmSharableApp::Next() API, I am getting all the running application handles in my machine and I am able to share the applications. I want to share my desktop, but I am not getting the handle to the running Desktop so that I can share the desktop. Is there any way I can get the handle to my desktop and share it so that any body joins the conference will be able to see my desktop.
Any help from any one will be highly appreciated.
Thanks & Regards
Shaini
|
|
|
|
|
Hi All,
I am implementing an MFC application which is using two COM DLL(say First.dll and Second.dll) files.
Both Dlls are having same coclass name and interfaces.Only their GUIDs are different.
To do the above, I have imported the tlb files for btoh the dlls i.e. A.tlb and B.tlb.
In the MFC application,I am using these interfaces like
CComPtr<isamename> m_pSameName;
m_pSameName.CoCreateInstance(__uuidof(SameName));
But the above was giving ambiguous error.To remove the error,I tried by importing type library without no_namespace attribute. And modified the above code to..
CComPtr<alib::isamename> m_pASameName;
m_pASameName.CoCreateInstance(__uuidof(SameName));
CComPtr<blib::isamename> m_pBSameName;
m_pBSameName.CoCreateInstance(__uuidof(SameName));
But this code appears that so much code to be in repetition as above.
Please suggest me to approach any better way to avoid these repetition.
Regards
jabhi1974
|
|
|
|
|
Maybe this work?
#import "A.tlb" named_guids
#import "B.tlb" named_guids
CComPtr<alib::samename> m_pASameName;
CComPtr<blib::samename> m_pBSameName;
...with the right names obviously
|
|
|
|
|
I am complete newbie in this field. I need to install DLL in MTS via VC++ 6.0 program. Any help is appreciable.
Thanks in advance.
|
|
|
|
|
What you mean.... you need to install the files in MTS via VC or you have build the COM in VC and want to install on MTS ?
any ways install the component on MTS and then export the package. which will give you the installation package for clients. which you can run to install on clients..run it through your VC program...
|
|
|
|
|
I want to perform all the steps of installation in MTS, exporting the package programmatically. Need a one-click go stuff.
|
|
|
|
|
well Pavneet I dont know exactly why you want to do this. What I used to do is the following
on my test machine I create a package in Transaction Server. then I export it as a server side package. Now this package can be installed on client and server both. So your setup is ready for transaction server for client. Now go to your Setup builder (install shield ,wise or dotnet built-in package builder ) and include this package to run at the end of the setup and give that package to client. when CLient will install the application the Components will be installed automatically with that. Why you want that client will install your application then he will get a new package from MTS to install on different machines.
if this helps you then great if not then wait for some one else who knows how to do this....
|
|
|
|
|
Hye Guys
I have deployed one distributed project. Client Side installation Plus Server Side (Transaction Server). when I use the object it works fine. next day it was not working without any reason (Server Components only). I tried hard uninstalled/reinstalled not working and some how accidently I came to know if I change the date of the system to the installation date. then it works fine. So I changed the date to installation date which worked successfully. So every time I have to run the application I need to change the date of my machine then it works fine other wise error
ActiveX Object Component create Object..429...
is there any communication or relation between date and COM Objects ??????
if yes which looks under my scenrio... then what is the solution...
|
|
|
|
|
Any idea how to embed an exectuable inside another executable, and then from with in your program, call the embeded exectuable with out creating another process or wrting the embed exectuable to disk?
I have a C++ program (straight C++, not managed). It has some logic and then depending on a number of conditions, ShellExecute()s another exectble file (client.exe), which happens to be a .net file. Is there anyway that I can add this client.exe file as a resource of my C++ program, and then call the beginning of the code from within the C++ program, so I wouldn't have to extract the resource or create a new process
Please help
Thanks,
Jason A. Donenfeld
PS: This is what I have now:
<br />
#define WIN32_LEAN_AND_MEAN<br />
#include<br />
#include<br />
#include<br />
<br />
#define INSTANCEMESSAGE "ShowZIM"<br />
#define WINDOW_TITLE "ZX2C4InstantMessenger"<br />
#define MUTEX_STRING "Local\\ZX2C4IM"<br />
#define FILE "client.exe"<br />
<br />
int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow)<br />
{<br />
if(_tcscmp(lpCmdLine,"clone"))<br />
{<br />
CreateMutex(NULL,TRUE,MUTEX_STRING);<br />
if(GetLastError()==ERROR_ALREADY_EXISTS)<br />
{<br />
SendMessage(FindWindow(NULL, WINDOW_TITLE), RegisterWindowMessage(INSTANCEMESSAGE), NULL, NULL);<br />
return 0;<br />
}<br />
}<br />
ShellExecute(NULL,NULL,FILE,lpCmdLine,NULL,SW_SHOW);<br />
return 0;<br />
}<br />
|
|
|
|
|
Why would you want to embed an executable?
If you need your code to be in your main executable, then compile it in at source level. I.e., call your code via function(s).
--
Schni Schna Schnappi! Schnappi Schnappi Schnapp!
|
|
|
|
|
I'm trying to have the program start in C++, and then if certain conditions are met, I want it to start calling the .net code. .Net is way slow, so I want the conditions to be checked with C++, so the runtime isn't started if the .net code isn't to be executed. I know I could just ShellExecute another executable, but that seems so sloppy.
|
|
|
|
|
Hi,All
I am developing a GDI graphics ActiveX Control with atl, it has a picture property.How can i set the picture value when i create the bitmap every time in the function OnDraw, the following is the my snippet code:
HRESULT OnDraw(ATL_DRAWINFO& di)
{
Graphics graphics(di.hdcDraw);
RECT& rc = *(RECT*)di.prcBounds;
Height = rc.bottom-rc.top;
Width = rc.right-rc.left;
Bitmap bmp(Width,Height);
Graphics * pMemoryGraphics=Graphics::FromImage(&bmp);
MyImage * img= new MyImage();
img->DrawGraphics(pMemoryGraphics); // draw the graphics
graphics.DrawImage(&bmp,rc.left,rc.top);
// here i created the bitmap "bmp", how to pass it to m_mPicture?
// CComPtr<ipicturedisp> m_pPicture;
I am very appreicated if someone can help.
Eric
|
|
|
|
|
I am having error as displayed below :-
System.Runtime.Remoting.RemotingException: Cannot load type MyRemoteCom1.MyRemot
eCom, RemoteComObj.
at System.Runtime.Remoting.RemotingConfigInfo.LoadType(String typeName, Strin
g assemblyName)
at System.Runtime.Remoting.RemotingConfigInfo.GetServerTypeForUri(String URI)
at System.Runtime.Remoting.RemotingConfigHandler.GetServerTypeForUri(String U
RI)
at System.Runtime.Remoting.RemotingServices.GetServerTypeForUri(String URI)
at System.Runtime.Remoting.Channels.Http.HttpRemotingHandler.CanServiceReques
t(HttpContext context)
at System.Runtime.Remoting.Channels.Http.HttpRemotingHandler.InternalProcessR
equest(HttpContext context)
I can't seem to be able to invoke a method that is actually a serviced component located in another server by using .Net Remoting
My codes are as such :-
For my client application calling the object :-
IMyRemoteCom objIMyRemoteCom = null;
try
{
objIMyRemoteCom = (IMyRemoteCom)Activator.GetObject(typeof(IMyRemoteCom), "http://127.0.0.1/ComRemoteServer/MyRemoteCom.rem");
Console.WriteLine(objIMyRemoteCom.RetrieveString());
}
catch ( Exception ex )
{
Console.WriteLine(ex.Message.Trim());
}
finally
{
objIMyRemoteCom = null;
}
Console.ReadLine();
For my COM+ Object :-
namespace MyRemoteCom1
{
///
/// Summary description for MyRemoteCom.
///
#region COM+ Declaration
[Transaction(TransactionOption.Supported)]
[Guid("16073B03-F2DF-4028-AFB8-8D001DB6F62A")]
[EventTrackingEnabled(true)]
[ObjectPooling(true, 2, 1000)]
#endregion
public class MyRemoteCom : ServicedComponent, IMyRemoteCom
{
#region Public : Constructor
public MyRemoteCom()
{
//
// TODO: Add constructor logic here
//
}
#endregion
#region Public : String : RetrieveString
public string RetrieveString()
{
return "MyRemoteCom Version 1.0.0.0";
}
#endregion
}
}
For my interface object :-
namespace MyRemoteCom1
{
///
/// Summary description for Class1.
///
public interface IMyRemoteCom
{
string RetrieveString();
}
}
For my config :-
wellknown mode="SingleCall" type="MyRemoteCom1.MyRemoteCom, RemoteComObj" objectUri="MyRemoteCom.rem"
~MicDevNet~configuration>
Please help
~MicDevNet~configuration>
Please help
~MicDevNet~
|
|
|
|
|