|
Really? It compiles without complaint on my end, also with VS 2008. It executes properly, too.
Is it perhaps time to consider the possibility that I have finally lost my mind?
|
|
|
|
|
Oddball wrote: Is it perhaps time to consider the possibility that I have finally lost my mind?
Or I have...wait, I KNOW I have, or have I?
Beats me what's going on there
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
I'm out of the office for the day. I'll take another look at it tomorrow. Maybe I'll see what insanity I have perpetrated, and we can all have a good laugh.
That or I'll schedule my commitment!
|
|
|
|
|
This whole thing is really starting to puzzle me. I'm just glad that what I have does work, and that I'm coming from the angle of curiosity, rather than desperation!
The exact line that I am executing is socket->BeginReceive(state->buffer, 0, state->BUFFER_SIZE, SocketFlags::None, gcnew AsyncCallback(this, &IOS::OnHostDataReceived), state); (variable declarations excluded for space considerations). This compiles and executes just fine for me under Visual Studio 2008 in a C++/CLI Windows Forms Project.
For reference, I found the advice that led me to try it this way at http://forums.msdn.microsoft.com/en-US/vclanguage/thread/7a261f03-8a11-4ab2-b705-a5d2d6b57eef/[^] (second post).
I guess I'm glad that it works, but I'm still puzzled about why. This strikes me as the sort of knowledge that could come in really handy in similar situations in the future.
Do you have any insight, Mark, or are you still as stumped as I am?
|
|
|
|
|
|
Oooooh, I get it now. Thanks a million, Mark. I feel much better about that bit of code now.
|
|
|
|
|
I have modified my C++ code from Manged Extensions to C++/cli. My code is using a class called CRadio that is in a dll that is written in C#. When I was using Manged Extensions I was able to call the Dispose function in the CRadio class. I am not able to do this using C++/cli because the compiler does not allow it. If I call delete on my managed CRadio class, the Dispose function and the finalizer never get called in the CRadio class.
Is there a way to execute the Dispose function or the finalizer of a managed class that is being accessed from C++/cli?
Craig
|
|
|
|
|
CTaylor89 wrote: Is there a way to execute the Dispose function
Yes. It is called when the class destructor (in C++) is called.
From the docs, this occurs:
If an object created using stack semantics goes out of scope. For more information, see C++ Stack Semantics for Reference Types.
If an exception is thrown during the object's construction.
If the object is a member in an object whose destructor is running.
If you call the delete Operator (C++) on a handle (^ (Handle to Object on Managed Heap)).
If you explicitly call the destructor.
For best results, study these carefully
Destructors and Finalizers in Visual C++[^]
Changes in Destructor Semantics[^]
Mark
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
Statement #4 "If you call the delete Operator (C++) on a handle (^ (Handle to Object on Managed Heap))" is what I have been attempting, but it does not result in a call to the Dispose function on the managed heap. The Dispose function of the object on the managed heap is called when my C++ destructor is called, but that requires my application to be shut down.
All I am simply doing is this:
CRadio^ pcsRadio = gcnew CRadio();
...
delete pcsRadio;
According to Statement #4 shouldn't the Dispose function of the managed object be called?
Craig
|
|
|
|
|
CTaylor89 wrote: According to Statement #4 shouldn't the Dispose function of the managed object be called?
Yes.
Is CRadio implemented in C++ or another language?
Mark
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
CRadio that is in a dll that is written in C#. It is being declared, initialized and used in a C++/cli application. I want to dispose of it from the C++/cli application. Microsoft however, does not want me to simply be able to call dispose on it.
Thier documentation states "Error C2039 can occur when attempting to write code that will deterministic release of your managed or unmanaged resources." Following their suggestion for further reading, I have not found an anser to this. Sometimes I think Microsoft hates C++ programmers.
Craig
|
|
|
|
|
No, you can't call Dispose() directly from C++.
Dispose() should be called when you use delete. Try this:
public class TestDisposable : IDisposable
{
private IntPtr handle;
private bool disposed = false;
public TestDisposable(IntPtr handle)
{
this.handle = handle;
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
private void Dispose(bool disposing)
{
if(!this.disposed)
{
if(disposing)
{
}
handle = IntPtr.Zero;
disposed = true;
}
}
}
TestDisposable ^testdisposable = gcnew TestDisposable(IntPtr(3));
delete testdisposable;
A breakpoint in the C# Dispose() method should be hit when delete is used.
Mark
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
Looking at your example got me to think about my managed class implementation. I had a Dispose method and it would even show up in intellisense. But I was not implementing IDisposable at the top of my class and apparently this matters to C++/cli even though it worked under managed extensions.
Thanks Mark for taking the time to help me.
Craig
|
|
|
|
|
CTaylor89 wrote: and apparently this matters to C++/cli
Yes! That's how the C++ compiler knows how to implement your delete
operator call on a managed handle.
Cheers,
Mark
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
Hi to all,
1. I have created a class (class library MyNameSpace.dll) in VC#.Net as follows,
namespace MyNameSpace
{
public class MyClass
{
public int Member_Variable;
}
}
How can I use this class in my new VC++.Net application?
Do I need to make any changes in my class library?
2. How to share a variable (of user defined type) in 2 different applications (one VC# application & other VC++ application) ?
3. Does anyone know the good Tool for class design. Where can I get Visio 2003 Enterprise Architect? Is it a good tool?
Regards,
Aniket A. Salunkhe
|
|
|
|
|
Aniket Salunkhe wrote: How can I use this class in my new VC++.Net application?
The same way you use any .NET classes. You'll need a reference to the DLL
in your project and you'll need to use the namespace, just like when using
the .NET framework classes.
Mark
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
Hi to u both,
Yes. Adding reference I get access to classes within that dll.
using namepsace MyDll;
Thanks to you both.
Thanks & Regards,
Aniket A. Salunkhe
|
|
|
|
|
Not tough to do. Just add a reference to the class in your C++.NET project.
"The clue train passed his station without stopping." - John Simmons / outlaw programmer
"Real programmers just throw a bunch of 1s and 0s at the computer to see what sticks" - Pete O'Hanlon
|
|
|
|
|
I wish to use BlowFish encryption for my project. How do I pass the value from the form textbox to the Blowfish Encrypt function?
The Blowfish algo is written in Classic C++, but the Form is in managed C++.
|
|
|
|
|
So your question has nothing to do with BlowFish. You want some one to tell you how to do mixed mode development, in an internet forum.
Typically that's not what these forums are for. Beginners are expected to use some instructional material ( University Courses, Books, Online tutorials, Online API References, Online Articles) to learn basics and fundamentals and then ask for assistance with specific problems in these forums. And in case you are thinking of posting another question, YES, there are a whole series of articles here on CodeProject that are introductory articles into CLI programming. Use searching or the menu system for the site in the left column but do it yourself rather than ask someone to provide you a link.
Your question is like: Teach me how to program?
led mike
|
|
|
|
|
|
Xaria wrote: wish to use BlowFish encryption for my project. How do I pass the value from the form textbox to the Blowfish Encrypt function?
The Blowfish algo is written in Classic C++, but the Form is in managed C++.
Why not just write a managed implementation of it. Can't be that hard.
"The clue train passed his station without stopping." - John Simmons / outlaw programmer
"Real programmers just throw a bunch of 1s and 0s at the computer to see what sticks" - Pete O'Hanlon
|
|
|
|
|
I am trying to do just that.
Thanks
|
|
|
|
|
Hello,
I am trying to access the SHGetKnwonFolderPath function on Vista from NET and I get an exception:
My code looks the following:
[DllImport("shell32.dll")]
extern "C" int SHGetKnownFolderPath([MarshalAs(UnmanagedType::LPStruct)] Guid^ rfid, unsigned int dwFlags, IntPtr hToken, IntPtr ppszPath);
ref class KnownFolders
{
public:
static const Guid^ AddNewPrograms = gcnew Guid( "de61d971-5ebc-4f02-a3a9-6c82895e5c04" );
... snip ...
};
When running the following code the runtime raises an exception that parameter #1 can not be marshaled as there is no layout information available
String^ str;
IntPtr path;
if(Shell32::SHGetKnownFolderPath((Guid^)KnownFolders::AddNewPrograms, 0, IntPtr::Zero, path) == 0)
{
str = System::Runtime::InteropServices::Marshal::PtrToStringAuto(path);
System::Runtime::InteropServices::Marshal::FreeCoTaskMem(path);
}
(
|
|
|
|
|
As the exception message indicates, without structure layout, the Guid can't be marshaled.
Using the info in "How to: Convert Between System::Guid and _GUID[^]", you could marshal
the Guid as a byte array, something like:
[DllImport("shell32.dll", CallingConvention = CallingConvention::Cdecl)]
extern int SHGetKnownFolderPath([MarshalAs(UnmanagedType::LPArray)] array<Byte> ^ar, UInt32 dwFlags, IntPtr hToken, [Runtime::InteropServices::Out] IntPtr %ppszPath);
...
String^ str;
IntPtr path;
array<Byte> ^ar = KnownFolders::AddNewPrograms->ToByteArray();
if(SHGetKnownFolderPath(ar, 0, IntPtr::Zero, path) == 0)
{
str = System::Runtime::InteropServices::Marshal::PtrToStringAuto(path);
System::Runtime::InteropServices::Marshal::FreeCoTaskMem(path);
}
Note I also changed the Path paramter so it would marshal as an Out parameter.
The "[Runtime::InteropServices::Out]" is optional - the "%" is NOT optional
Mark
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|