|
Loading a managed C++ dll from a non-managed executable works as expected when it is loaded from a local directory. However, when loading the same dll from the same executable over a network path a FileLoadException is thrown: "Failed to grant minimum premission requests". Is there a way to decrease the DLL's security or must the computer's settings be changed in order for things to work correctly?
Thanks!
Doug
|
|
|
|
|
As far as I know you can do this through the manifest file.
Scott Dorman Microsoft® MVP - Visual C# | MCPD
President - Tampa Bay IASA
[ Blog][ Articles][ Forum Guidelines] Hey, hey, hey. Don't be mean. We don't have to be mean because, remember, no matter where you go, there you are. - Buckaroo Banzai
|
|
|
|
|
The managed C++ dll is strongly named and the C++ program has a reference to it. I thought that should take care of any such issues. What else do I have to do?
Doug
|
|
|
|
|
I don't think strong naming it is enough. That will help the load time and allow you to register it in the GAC, but it doesn't affect the security policies about running from a network location. There is something you can add to the manifest file which says that it's safe to run from a network location, I just don't remember what it is offhand.
You can also try using fuslogvw (http://msdn.microsoft.com/en-us/library/e74a18c4.aspx[^]) to help identify what the loader is trying to do.
There is also some information here[^] that might help.
Scott Dorman Microsoft® MVP - Visual C# | MCPD
President - Tampa Bay IASA
[ Blog][ Articles][ Forum Guidelines] Hey, hey, hey. Don't be mean. We don't have to be mean because, remember, no matter where you go, there you are. - Buckaroo Banzai
|
|
|
|
|
I have some unmanaged code that invokes a callback function to display a series of bit map images in a picturebox in a managed GUI.
The unmanaged code is called from a worker thread, it loops, creating the bitmap images and passing the image address and a serial number as parameters to the callback routine. When all the images have been displayed the unmanaged code finishes, and the worker thread terminates.
The callback routine copies the bitmap to a stream and uses invoke to get the gui to display the image.
The images are set to display at 1/second.
I thought I had everything working nicely, but after about 30 seconds everything dies and a 'Buffer Overrun' message is generated.
The error is generated when/in/by calling the callback routine. If I don't invoke the callback all is ok. If I invoke the call back but do nothing except return immediately everything still goes wrong after about 30 seconds.
If I make the delay 10 sec everything runs happily for about 100 seconds, but then dies again.
I've reduced the code to a simple skeleton, but still get the crash.
The unmanaged code is called using a delegate, GCHandle, and Marshall::GetFunctionPointer.
I suspect something to do with garbage collection, or the lifetime of a thread, but I'm tearing my hasir out over this.
Can anyone suggest what I may have overlooked?
Bob Swan
|
|
|
|
|
Is the buffer overrun message because of an exception?
If so, what code is executing at the point the exception
is thrown?
Mark
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
None that I can see.
Normally the error is flagged when the callback is returning to the unmanaged code. The .net code that does all the cleanup and overrun checks as part of the return statement detects that the marker bytes have been modified.
I have run the code with visual studio monitoring the memory locations, (a breakpoint that continues when triggered) I can see that the markers are being overwritten. I can see that the data corrupts, but not what is doing it. This occurs even when all I am doing is calling the callback from a loop, and that does nothing except return.
In the original unmanaged code there were number of cout statements
which tended to flag the error, especially if you piped several items to the output. But I believe that was just because they also ran code that performed clean up checks. They also don't appear in my simple system.
I have ruled out the hardware problems as this occurs under Windows XP + studio 2005 or Windows 200 +studio 2008 Express.
I feel sure its something stupidly obvious.
BoB Swan
|
|
|
|
|
Well I've found one stupid error that corrects my simple version of the program.
when declaring the callback function pointers I had failed to define the calling convention as _stdcall
See stupid, maybe not obvious.
Bob Swan
|
|
|
|
|
|
ref class MyDummy
{
public:
void SayHelloTo(String ^str)
{
Console::WriteLine(str);
}
~MyDummy()
{
Console::WriteLine("Destructor called");
}
};
int main(array<System::String ^> ^args)
{
MyDummy ^myDummy = gcnew MyDummy();
myDummy->SayHelloTo("Name1");
delete myDummy;
myDummy->SayHelloTo("Name2");
return 0;
} In the above code, I am deleting handle myDummy after first call to SayHelloTo method. I can see that the destructor is getting executed but the next call to SayHelloTo after delete, worked correctly. How this can happen? After destruction, how it can be used again?
Any help would be great
|
|
|
|
|
You should make it a habit to set your handles to nullptr after explicitly deleting them.
delete myDummy;
myDummy = nullptr;
myDummy->SayHelloTo("Name2");
The explicitly deleted object instance may stick around for a while before the GC actually releases the resource.
"We make a living by what we get, we make a life by what we give." --Winston Churchill
|
|
|
|
|
George L. Jackson wrote: The explicitly deleted object instance may stick around for a while before the GC actually releases the resource
But AFAIK, when delete is used, we are not waiting for GC to collect the object. We are doing deterministic destruction, isn't it?
|
|
|
|
|
N a v a n e e t h wrote: But AFAIK, when delete is used, we are not waiting for GC to collect the object. We are doing deterministic destruction, isn't it?
If the type was allocated using gcnew you are waiting for the GC to collect the object.
Scott Dorman Microsoft® MVP - Visual C# | MCPD
President - Tampa Bay IASA
[ Blog][ Articles][ Forum Guidelines] Hey, hey, hey. Don't be mean. We don't have to be mean because, remember, no matter where you go, there you are. - Buckaroo Banzai
|
|
|
|
|
According to this[^], the call to delete will call the types destructor if it has been allocated with gcnew . As a result, while the object has been disposed it may still be around if the GC hasn't run a collection cycle yet.
Scott Dorman Microsoft® MVP - Visual C# | MCPD
President - Tampa Bay IASA
[ Blog][ Articles][ Forum Guidelines] Hey, hey, hey. Don't be mean. We don't have to be mean because, remember, no matter where you go, there you are. - Buckaroo Banzai
|
|
|
|
|
Yeah.. I came to know about it. I thought it will work like in standard C++. It is a syntactic sugar like C# uses using to call Dispose.
BTW, then claiming C++/CLI as the only .NET language which supports deterministic destruction is not correct, right?
|
|
|
|
|
N a v a n e e t h wrote: claiming C++/CLI as the only .NET language which supports deterministic destruction is not correct,
Correct. None of the .NET languages truly support determistic destruction. Keep in mind that when a call to Dispose is made, two things are supposed to happen (it is up to you to ensure that they actually do happen, however):
1. Any managed objects have their Dispose method called.
2. Any unmanaged resources are released.
Given that scenario you might say that .NET can be determistic when it comes to releasing unmanaged resources but not managed resources.
However, just because Dispose has been called doesn't mean the object has been deallocated on the heap. That only happens when a GC cycle runs and determines that the object is eligible for collection.
Scott Dorman Microsoft® MVP - Visual C# | MCPD
President - Tampa Bay IASA
[ Blog][ Articles][ Forum Guidelines] Hey, hey, hey. Don't be mean. We don't have to be mean because, remember, no matter where you go, there you are. - Buckaroo Banzai
|
|
|
|
|
Thanks scott
|
|
|
|
|
Scott:
I had further discussion on MSDN forum on this topic. If you are interested, follow this link[^].
|
|
|
|
|
Hmmm...link appears to be down at the moment. I will check it again later.
Scott Dorman Microsoft® MVP - Visual C# | MCPD
President - Tampa Bay IASA
[ Blog][ Articles][ Forum Guidelines] Hey, hey, hey. Don't be mean. We don't have to be mean because, remember, no matter where you go, there you are. - Buckaroo Banzai
|
|
|
|
|
Hello I am having real trouble with the following code.
System::Boolean vDataEvent16::IsSet::get()
{
System::Boolean data = (System::Boolean)(((* _Event) & 0x01) != false);
return data;
}
I get an invalid cast exception. How would I overcome this?
_Event is defined as a System::UInt16 ^ _Event and is passed in from C# assembly to the class constructor.
I wanted to use unions with some structs to view bits in the struct as individual properties but I could not cast the System::UInt16 to an unsigned short or rather to an unmanaged value type either.
Any suggesions
Really appreciate the response.
thanks
-Peter
|
|
|
|
|
peterdrozd wrote: I get an invalid cast exception.
In VS2008 I cannot reproduce the exception
led mike
|
|
|
|
|
peterdrozd wrote: != false
You're comparing a UInt16 with false.
That should be != 0
System::Boolean vDataEvent16::IsSet::get()
{
return (((*_Event) & 0x01) != 0);
}
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
Did you reproduce the exception? Using what version of C++?
led mike
|
|
|
|
|
led mike wrote: Did you reproduce the exception?
No sir (VS 2008 SP1).
I don't know what's up with that - not enough info for me.
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
Mark Salsbery wrote: I don't know what's up with that - not enough info for me.
Yeah I know, I plugged this in and ran it just fine
System::Boolean data = (System::Boolean)(((* _Event) & 0x01) != false);
led mike
|
|
|
|