|
Why not pass sender as a parameter if your method needs that information?
One obvious detail is that the callee may know nothing about the caller. For example, in a third party component that your program calls. The third party component won't know anything about your objects so what can it do with them? If it is all your own code then I think its time to step back and re-examine the design.
"You can have everything in life you want if you will just help enough other people get what they want." --Zig Ziglar
The Second EuroCPian Event will be in Brussels on the 4th of September
Can't manage to P/Invoke that Win32 API in .NET? Why not do interop the wiki way!
|
|
|
|
|
TuringTest1 wrote:
suppose i am a method and want to know the instance of the class calling me
OK, here goes. Obviously, the instance is available because, when using the debugger, you can click on the prior calls in the stack. That takes you to the caller code, and then you can inspect variables in that instance.
However, what exactly would you do with the instance yourself? The way the debugger gets it is because the class instance is either stored in a CPU register or is somehow obtainable by inspecting the stack (I can't remember if "this" gets pushed or not). Anyways, it's just an address. The debugger is doing some magic by converting the pointer to a class. In C++, that's easy, but in C#, I'm not sure it's possible.
Marc
Microsoft MVP, Visual C#
MyXaml
MyXaml Blog
|
|
|
|
|
Marc, Colin, thanks. Here is a brazen plug-- anyone reading this thread should read MyXaml-- it's way cool.
Responding to Colin's question, if "sender" is only used in very odd cases i want to put the plumbing underground where it belongs. I admit that this is an asthetic judgement, but it makes sense to me. Your code might detect an unusual condition several levels down and want to know the value of something at the top level-- certainly you could percolate this data or create some sort of global variables etc, but in my asthetic sense it's much more appealing to go and grovel for the data in the rare cases when it's needed rather than forcing everybody to look at your dirty laundry all the time. Imho it's exactly analogous the exception handling, you *could* achieve the same effect by passing all kinds of return flags around, but popping the stack is so much more comprehensible.
Back to the question, as Marc asks, how does the debugger do it? the debugger has no problem displaying all the local variables etc. I *assume* the values or pointers are simply coming from the stack. It's also clear that the debugger sometimes gets confused, so examining the stack isn't a slam dunk. What i don't know for a fact that external information gotten from compiling "Debug" isn't required. Also as Marc points out, what i really want isn't exactly the class instance but rather the contents of the field instance.Foobar-- i'm assuming that c# internally uses some sort of pointer and that if i'm either in the correct namespace or able to use reflection that given the instance pointer or whatever it should be easy to get the value of Foobar.
Anyway why would StackFrame return all the cool type information if it wasn't useful? I have to believe Stackframe is intended for more than just getting the NAMES/ signatures of the methods on the stack.
Again, thanks, and thanks in advance for any more hints.
_______________________________________________
Go see Shrek2. Tell me if it isnt the best movie ever. Then read the credits at the end of the movie and estimate the animation budget.
|
|
|
|
|
run tlbimp on cordebug.tlb in the lib dir of the SDK root. That should give you enough to play with (unfortunately its still in my to look at list, so gimme a shout if it works well).
top secret xacc-ide 0.0.1
|
|
|
|
|
Thanks be to Leppie! (can't claim i understand it quite yet but google cordebug seems to be the place to look).
Again, thanks!
________________________________________
Gosh, it would be awful pleas'n, to reason out the reason, for things I can't explain.
Then perhaps I'd deserve ya, and be even worthy of ya..
if I only had a brain!
|
|
|
|
|
TuringTest1 wrote:
is that because interpreting the actual data on the call stack is language dependent,
No, because all languages targeting the CLR compile to Intermediate Language, or IL. The source language you use to write an assembly has little to do with the compiled code (though some compilers support different features of the CLI and compiler optimizations can change the IL a small amount).
Microsoft MVP, Visual C#
My Articles
|
|
|
|
|
Is there a function which given a pathname will return the size of that file in bytes?
Thanks.
|
|
|
|
|
well, use the fileinfo class.
|
|
|
|
|
Thanks, I was looking at that class but missed "Length" - sometimes I can't see the wood for the trees.
Rugby League: The Greatest Game Of All.
|
|
|
|
|
new FileInfo("myPath").Length
|
|
|
|
|
Hi guys
Here is my problem without further ado :-
Let's say I have a COM method as follows -
HRESULT GetHerName([in] LONG id,
[out,retval] BSTR* namestr);
And I've implemented it as -
STDMETHODIMP MyClassHere::GetHerName(LONG id, BSTR* namestr)
{
wchar_t str[100];
*namestr = SysAllocString(str);
return S_OK;
}
Now C# sees this method as -
string GetHerName(int)
and I can use it from C# as :-
string s1 = obj.GetHerName(22);
string s2 = obj.GetHerName(14);
Now my problem is as follows - I have allocated a new BSTR using SysAllocString in my COM method, but this BSTR gets copied into a new String object by the RCW layer. All that's nice for me - but the original BSTR now leaks.
When I originally designed my COM method, my idea would probably have been that the client should free the BSTR using SysFreeString after using it.
But now I do not have such an option.
Anyone knows if RCW handles this for me in some way? Or will memory keep leaking every time GetHerName is called?
Now with my own blog - void Nish(char* szBlog);
My MVP tips, tricks and essays web site - www.voidnish.com
|
|
|
|
|
Hey, Nish...
When working with COM interop, be sure to check out the System.Runtime.InteropServices.Marshal class. It can be very helpful.
For example, there is a Marshal.FreeBSTR method. All this does is call SysFreeBSTR for you, but saves you from having to P/Invoke it yourself which saves you from requiring an extra code access permission or two (unless you P/Invoke'd other APIs). The trick is that Marshal.FreeBSTR requires an IntPtr - the address to the BSTR . You can get the address like so:
private void FreeBSTR(string bstr)
{
GCHandle handle = GCHandle.Alloc(bstr);
try
{
Marshal.FreeBSTR(handle.AddrOfPinnedObject());
}
finally
{
if (handle.IsAllocated) handle.Free();
}
}
Microsoft MVP, Visual C#
My Articles
|
|
|
|
|
Hey Heath,
Thanks for the reply.
So are you saying that, the string object that the RCW layer returns to the C# client will still internally refer the BSTR memory?
I'd have thought that the original BSTR returned from the COM method is ignored once its contents are used to construct a new string object.
Heath, are there any MSDN links or articles that explain how RCW internally works?
Thanks once again for some really interesting info
Nish
Now with my own blog - void Nish(char* szBlog);
My MVP tips, tricks and essays web site - www.voidnish.com
|
|
|
|
|
Internally, no. The best you could do is search Microsoftie blogs and see what you can find. In the .NET Framework SDK and other articles I've seen on MSDN, it's mostly higher level stuff.
Instead of having your method return a marshaled string have it return an IntPtr (may require hand-coding the RCW) and use Marshal.PtrToStringBSTR . After calling it, use Marshal.FreeBSTR with the IntPtr return value since Marshal.PtrToStringBSTR creates a copy, which implies you are indeed right. Guess I didn't consider that, though it does make complete sense. Maybe I should've slept in longer on this Saturday morning.
Microsoft MVP, Visual C#
My Articles
|
|
|
|
|
Thanks a heap, Heath
I was writing a blog entry for my blog on this RCW issue of returning a BSTR and was just wondering if perhaps RCW internally solves this issue. So I didn't want to write something without first confirming that the issue does exist.
I'll remember to thank you in my blog entry
Heath Stewart wrote:
Maybe I should've slept in longer on this Saturday morning.
Sleep does you a world of good Get as much of it as possible as you'll probably get busier in the near future as you land up lucrative sub-contracts and stuff.
Nish
Now with my own blog - void Nish(char* szBlog);
My MVP tips, tricks and essays web site - www.voidnish.com
|
|
|
|
|
Nishant S wrote:
...as you land up lucrative sub-contracts and stuff.
Man, I wish...
Microsoft MVP, Visual C#
My Articles
|
|
|
|
|
i took two listbox web server controls..ok
In My Listbox1 there is some data which comes from database
on client side i added some elements from listbox1 to listbox2 i have done this by using javascript ok...
Now on some event my page is going to refresh.. so what ever the data i have add on client side in listbox2 vanishes as page get refresh..
what i think as .Net provide a view state so how it get vanishes ....
so can u tell me where i m wrong...
the reason behind to think so, is that (if we add some data in text box through javascript or we just enter through our key board) and when it do the server trip it remains there ,then why not for list box.. so please help me and tell me where i m wrong...
thanks in advance...
|
|
|
|
|
|
Hai all...
I was trying to pass a class to an Unmanaged function. The class has a member of type, of the same class. Is it possible to pass a Managed class(Class having a member of it's own type) to an Unmanaged function.
Thanks in advance
Below is what i did...
This is the class i created to pass into an Unmanaged function as parameter
[StructLayout(LayoutKind.Explicit )]
public class MyWindow
{
[FieldOffset (0)]
public String className;
[FieldOffset (16)]
public String caption;
[FieldOffset (32)]
public MyWindow child ;
}
But if i remove the class member 'child' from the class it works well.
Unmanaged function Decleration
[DllImport("user32")]
public static extern bool EnumChildWindows(int hwndParent, EnumChildDelegare lpEnumFunc, MyWindow lParam) ;
This is the way how i call the unmanaged function
MyWindow m = new MyWindow ();
Win32Calls.EnumChildWindows (winHandle,w.enumChildDlgate ,m);
And i am getting this error.
An unhandled exception of type 'System.TypeLoadException' occurred in CSRecorder.exe
Additional information: Can not marshal field child of type CSRecorder.MyWindow: This type can not be marshaled as a structure field.
Shaju Mathew
|
|
|
|
|
First, change the class to a struct. This allocates the data on the stack so it will not be moved. While this isn't the direct cause of your problem, it may lead to them. If it's a class - which is allocated on the heap - the GC (Garbage Collector) may move it when necessary and your handle that your enumerator is using would be invalid. Declaring this as a struct should also fix the other error.
There is a problem with your EnumChildWindows as well. An HWND is a processor-dependent type. You should really declare this as IntPtr , which works well since P/Invoking other unmanaged Windows APIs will use IntPtr and Control.Handle (the HWND for the control) is also of type IntPtr . Any native int or unsigned int should be declared as an IntPtr .
Also, for your struct, just use LayoutKind.Sequential . You really don't even need that, however, since the memory address to your struct's instance is being passed to your enumerator so it doesn't need to be marshaled for use with unmanaged code. Just a couple of tips.
Microsoft MVP, Visual C#
My Articles
|
|
|
|
|
Thanks... Heath Stewart
The tips helped ..
But i cannot change class to struct. Since struct won't allow the same struct as a member
Shaju Mathew
|
|
|
|
|
In that case, use a GCHandle to pin the class instance in memory. The GC (Garbage Collector) may relocate the object in memory, so the address would change. Unmanaged code can't deal with those changes so you'll get all sorts of errors since your object isn't where it's supposed to be.
You can find more information about the GCHandle class in the .NET Framework SDK.
Microsoft MVP, Visual C#
My Articles
|
|
|
|
|
When I was marshalling EnumChildWindows, I declared the function like that:
[DllImport("user32.dll",SetLastError=true)]<br />
public static extern bool EnumChildWindows( <br />
IntPtr hWndParent,<br />
User32Functions.EnumWindowsCallback lpEnumFunc,<br />
IntPtr lParam<br />
);
The point is, why do you need to pass a class or struct as the third parameter?
I followed the MSDN recommendation and called the function like that:
GCHandle gch=GCHandle.Alloc(this.twHandles);<br />
User32.EnumChildWindows(handleParent,this.enumThreadCallback,(IntPtr)gch);<br />
gch.Free();
Here this.twHandles is a text writer, which i later (in the callback function) use like so:
private bool CaptureEnumThreadWindows(int handle, IntPtr param)<br />
{<br />
GCHandle gch=(GCHandle)param;<br />
TextWriter tw=(TextWriter)gch.Target;<br />
twHandles.Write(handle.ToString()+" ");<br />
twHandles.Flush();<br />
return true;<br />
}
Anyway, MSDN recommends to use GCHandle , 'so the delegate does not get moved by GC before the call ends, however I was trying to use without GCHandle, just passing IntPtr.Zero as the last parameter and it works anyway. Frankly I don't understand how this (GCHandle) can prevent the delegate from being moved by GC, but that's what MSDN says. (see GCHandle sample)
|
|
|
|
|
Thanks Ael
GCHandle worked well And it solved my problem.
Shaju Mathew
|
|
|
|
|
Hy.
My problem is that I'm new in this field (DirectShow filter) and I need to use a particular filter in my app.
I think is possible but I really don't know how.
So , I have a DirectShow filter with the AX extension (executable , I think)
written in C++ and I want to use it in my C# app.
Can anyone help me ?
Thanks.
Angel
|
|
|
|