|
The GnucDNA is a component for building P2P applications. It is written in C++. Examples of how to call it from VB.NET and C#.NET can be seen at http://www.gnucleus.com/GnucDNA/docs/examples.html. Works fine for most methods in GnucDNA, but one crucial call to a method called SetSharedDirs is not shown in the examples, and for a good reason: It does not work, it requires the argument to be passed as a string array pointer.
Looks like Microsoft is trying to explain something about how to do it by marshalling at http://samples.gotdotnet.com/quickstart/howto/doc/Interop/StringMarshal.aspx. Also, seem like using unmanaged code in C# by declaring keyword “unsafe” and statement “fixed” may hold a key, but how?
The C++ - method in the .COM can be seen at http://cvs.sourceforge.net/viewcvs.py/gnucleus/GnucDNAR2/ComShare.cpp?sortby=date&view=markup, and looks like so:
void CComShare::SetSharedDirs(VARIANT* pDirPaths)
Anybody able to come up with a call from VB.NET or C#.NET that does not produce a type mismatch – error?
|
|
|
|
|
I hope someone might be able to answer this puzzle that I've found while testing a component of mine.
I am using Excel's VBA environment to quickly test a few of the methods in my component. Now if I create my component, specifying the type explicitly and run the method, everything works OK.
eg:
<code>
Dim Obj as MyItem
Dim strTitle As String
Set Obj = New MyItem
strTitle = "Some Description"
call Obj.SetTitle(2057, strTitle)
Set Obj = Nothing
</code>
Now here's the weird bit. If I create my item from an Object variable, it fails on my call to the same method. So if I change my code to:
<code>
dim Obj as Object
Dim strTitle As String
Set Obj = New MyItem
strTitle = "Some Description"
<font color=red>call Obj.SetTitle(2057, strTitle)</font><font color=green>' This FAILS with 'Type Mismatch' error </font>
Set Obj = Nothing
</code>
I can get access to the other properties of the item, but for some reason, it will not call this function.
Am I missing something?
There must be a simple explanation for this.
I Dream of Absolute Zero
|
|
|
|
|
UPDATE
Its gets stranger.
If I replace the String variable by a litteral text, it works!!
call Obj.SetTitle(2057, "Hello") 'Works!!
WTF! Are string types treated differently when called via an Object type?
Why is this happening ? Someone enlighten me.
I Dream of Absolute Zero
|
|
|
|
|
Are string types treated differently when called via an Object type?
Of course. Strings can be passed by VARIANT with VT_BSTR (your second case) or VT_BSTR|VT_BYREF (your first case).
Probably, the Invoke-helper for your class cannot process this vt-value.
Set the breakpoint inside Invoke(...) of your class and test it.
PS
Your can also get the valid result with extra parentheses around String.
call Obj.SetTitle(2057, (strTitle))
With best wishes,
Vita
|
|
|
|
|
Cheers.
I suspect it does have to do with parameters passed via Variant, ByValue, By reference, or a combination thereof I don't want to spend too much brain time in the VBA environment, so as long as it works
I solved the problem by explicitly casting the type value. So this works:
<br />
call Obj.SetTitle(CInt(2057), CStr(strTitle))
I Dream of Absolute Zero
|
|
|
|
|
Hi all,
I create a COM in VC++. It has a funtion that returns a SAFEARRAY (IDispatch*)
. if I use this Com in c++, it works fine, but if I call this function in matlab, it causes problem.
Does any one have experience on it?
Thank you for any help.
Tran Phuong Nga
|
|
|
|
|
Try wrapping it into a VARIANT instead.
I.e.
HRESULT MyMethod([out,retval] VARIANT * pVar);
And the variant is initialized like this (roughly):
VARIANT l_var;<br />
VariantInit(&l_var);<br />
l_var.vt = VT_DISPATCH | VT_ARRAY;<br />
l_var.parray = your_safe_array;
|
|
|
|
|
Hi,
thank you for your help.
But the problem comes from the following code:
SafeArrayCreateVector(VT_DISPATCH, 0, length);. If I hide this code, no problem any more.
If the code is SafeArrayCreateVector(VT_INT, 0, length); or SafeArrayCreateVector(VT_BSTR, 0, length);.., no problem.
So eventhough I wrap the return value into VARIANT type, I still have to call SafeArrayCreateVector(VT_DISPATCH, 0, length);, then the problem is still there.
Do you know how to solve it, or is there any other ways to create a vector of IDispatch*?
Thank you.
Nga
|
|
|
|
|
Does anyone know if there is a way how to export emails from the Inbox/Outbox into .msg files programmatically?
I tried using the Outlook Object Model, but it asks the user for permission to access the mailboxes and ideally I would like to avoid that (no, i'm *not* writing a virus... - i just would like to do away with user interaction while the program is running ).
I also tried using MAPI, and i managed to read emails individually into the IMessage interface, but I can't see how I can stream its properties to a file without iterating on the properties one by one (and potentially risking modifying one property indadvertedly and ruining the entire message).
My recent attempt has been with CDO but again, the MessagePtr interface in cdo.dll doesn't seem to support any streaming.
Anyone has a better idea?
|
|
|
|
|
|
Hi,
I have a com DLL that I am utilising in an ASP net application. When I use the COMM DLL in a windows form application an when I call methods on the DLL there is no problem, when I use the the DLL in a asp.net application I get the following error : "System.Runtime.InteropServices.SEHException, Message : External component threw an error". What could be the problem, where do I start looking for the error ?
Vinesh
|
|
|
|
|
Hi all !
I was assigned a task which I don't think is possible to do.
What I was requested to achieve is basically the following:
To cause our existing MFC (Doc/view) application to become a COM EXE server !
Is it possible at all, or am I wasting my time. If it's not possible, what approach shall I take?
I used the information which appeared under the article :
Article ID :175190
Last Review:June 29, 2004
Title : How to add ATL support to an MFC EXE
Link : http://support.microsoft.com/default.aspx?scid=kb;EN-US;175190[^]
Outcome so far : NOT Successful, meaning, the registration is not failing, but the server cannot be found by a client application (class not registered !)
As far as I understand , the article 175190 discusses the option of
embedding an "local In-process COM server" into the application, not a "remote COM EXE server".
I tried everything I know, so far with no results..
Please help,
Rubi
|
|
|
|
|
I can assure you that it is possible, as I have been forced to do the same myself in the past. How I approached the problem was to build test out-of-process MFC EXE applications from scratch using the MSVC wizards, and contrasted that with a similar standalone EXE application without ATL, and researched each extra line added by the wizard. I must admit that the MS article that you have found looks to be good, and if I had had found the same article it would have saved me much time.
One of the problems that I remember was in coding the clients. For a straight automation enabled MFC SDI application, the client calls the IMyApp.Document interface, which you can access via CreateDispatch() and related function. If you were building a COM EXE server without a document interface, the client interface initialized using CoCreateInstance(). This may be the source of your problem.
Feel free to ask more specific question, and I will do my best to remember.
|
|
|
|
|
I would also recommend using the OLE/COM Object Viewer to establish whether your interface has been correctly registered.
You could write a short VBScript to test your server. If this works, then you would know that you have a problem with your client.
In response to your email, please note that I unable to debug your code for you, as I do not have the time and I do not need the acknowledgement. I am willing to help through these postings on this message board just as long as this is a two-way process.
|
|
|
|
|
|
First of all thank you "FearlessBurner" for your interest and swift response !
I finally found the bug , which caused my "COM EXE Server / MFC Doc View hybrid" not to register properly. A line of code is missing in the Microsoft sample code (can happen, of course) . Here is an extract of the inserted code section from article Q175190, inluding the missing line (indicated as such).After inserting the line I stopped receiving the "Class not registered" error messagbox alerts (caused by the missing line "OBJECT_ENTRY(CLSID_ImageProcess, CImageProcess)") :
CExeModule _Module;
LONG CExeModule::Unlock()
{
LONG l = CComModule::Unlock();
if (l == 0)
{
#if _WIN32_WINNT >= 0x0400
if (CoSuspendClassObjects() == S_OK)
PostThreadMessage(dwThreadID, WM_QUIT, 0, 0);
#else
PostThreadMessage(dwThreadID, WM_QUIT, 0, 0);
#endif
}
return l;
}
BEGIN_OBJECT_MAP(ObjectMap)
OBJECT_ENTRY(CLSID_ImageProcess, CImageProcess) <--- ----------------------------------------------MISSING LINE
END_OBJECT_MAP()
LPCTSTR FindOneOf(LPCTSTR p1, LPCTSTR p2)
{
while (*p1 != NULL)
{
LPCTSTR p = p2;
while (*p != NULL)
{
if (*p1 == *p++)
return p1+1;
}
p1++;
}
return NULL;
}
Source code available to anyone requesting (Client and server demo applications)
Send your email address...
Rubi
|
|
|
|
|
Excellent. I am very pleased that you were able to discover the problem yourself and put it up as a response. This should benefit the next programmer who wants to do something similar.
|
|
|
|
|
I have an object that calls a private method, 'populate', in a loop. I need each call to 'populate' to initiate a COM+ transaction.
'populate' instantiates and uses external objects which are configured to participate in the root transaction, but without creating a new root object with only a 'populate' method, I don't know how to initiate and commit the transaction.
Don't get ripped-off by the life assurance industry.
|
|
|
|
|
Hi,
I was wondering whether its a good practise to use optional[^] attribute in IDL. Also I would like to know about using defaultvalue attribute along with optional attrbute.
Please help me with this.
Have a great day ahead!
Regards,
Sohail Kadiwala
(My Blog - http://blogs.wdevs.com/sohail/[^])
modified 21-Apr-21 21:01pm.
|
|
|
|
|
|
MSComm32.ocx has the properties:
1) HRESULT CommID([in] long plCommID);
2) HRESULT CommID([out, retval] long* plCommID);
Note: lCommID is the handle to comm-port.
Now according to the MSDN Library, only the second one exist and is only accessible at run-time.
Question: Is it possible to assess the first one at run-time, in order to supply an existing handle.
I am writing a simple replacement TAPI control (replacing an existing unsupport simple control). The customer would prefer it is I used the MS Comm control, instead of the current Comm control (from same company as origanal TAPPI control).
Note: Origanal TAPI control has a bug in it.
Thanks!
INTP
"The more help VB provides VB programmers, the more miserable your life as a C++ programmer becomes."
Andrew W. Troelsen
|
|
|
|
|
How to have a safearray with of its data type as Safearray itself? How to put and get SafeArray within a safearray
Eg:Safearray of type VT_VARIANT can have int(VT_INT),bstr(VT_BSTR)similarly its should also safearray(VT_ARRAY)
Alamelu
|
|
|
|
|
I tried to make a DCOM, and got one problem, it work allright when the dll is placed on my computer with Windows XP, and client on another computer with the same OS, but if another computer Windows 2000 or something else it doesn't work, and client programm says "Invalid Pointer"
|
|
|
|
|
|
Hi there,
Can anyone tell me how to set the initial postion of a deskband.
I have succesfull executed the Band Object Implementation Sample from MSDN
But the desk band Initially is always, docked on the taskbar.
What I want is, initially, the deskband to be docked on the right side of the screen.
Thanks in advance,
Kumar.
|
|
|
|
|