Answered by:
Specified cast is not valid!

Question
-
Hi All,
I defined a delegate in my main form class (MyForm) as follows:
public: delegate void Del; Del^ myDelegate;
Then I tried to access it via the following code:
private: System::Void MyForm_Activated(System::Object^ sender, System::EventArgs^ e) { myDelegate = gcnew Del(this, &MyForm::Func2); } private: void Func2() { ... } private: static void ThreadProc(System::Object ^obj) { MyForm^ ob= (MyForm^) obj; ob->Invoke(ob->myDelegate); // I got the exception here }
But I got an exception saying "Specified cast is not valid" on "ob->Invoke(ob->myDelegate);" but what is the problem and how can I solve that? ThanksMonday, July 5, 2010 10:16 PM
Answers
-
Then you need to do 'gcnew ParameterizedThreadStart(this, &MyForm::ThreadProc)', similarly to how you're doing Func2.
You still have 'gcnew ParameterizedThreadStart(&MyForm::ThreadProc)'.- Marked as answer by RedHat_Doom Wednesday, July 21, 2010 12:47 AM
Monday, July 19, 2010 9:33 PM
All replies
-
Hi RedHat,
If your delegate method accepts 0 parameter, it should be declared as
delegate void Del();
Yi
Cheers,
Please remember to mark the replies as answers if they help and unmark them if they provide no help.
Welcome to the All-In-One Code Framework! If you have any feedback, please tell us.- Proposed as answer by Yi Feng Li Monday, July 12, 2010 3:51 AM
- Marked as answer by Yi Feng Li Tuesday, July 13, 2010 3:16 AM
- Unmarked as answer by RedHat_Doom Tuesday, July 13, 2010 7:45 PM
Wednesday, July 7, 2010 8:37 AM -
Hi Yi,
Thanks for your help. I applied what you mentioned but I got another exception: Attempted to read (or write) from the protected memory!
I checked the call stack, and the exception is raised here: ob->Invoke(ob->myDelegate);
But what is the problem? Thanks,
Tuesday, July 13, 2010 7:48 PM -
Hi RedHat,
It seems like the object obj doesn’t contain the correct member. I suggest you double check the obj, make sure it contains everything you required in the thread function. Does the Object is a form? Or it contains other structure?
If you pass “this” as an object to the thread function, has the myDelegate already been created? This means myDelegate should be created first then it can be used for Invoke.
Cheers,
Yi
Please remember to mark the replies as answers if they help and unmark them if they provide no help.
Welcome to the All-In-One Code Framework! If you have any feedback, please tell us.Wednesday, July 14, 2010 2:19 AM -
Thanks Yi,
obj is a Form. Actually, I have two forms: MainForm and MyForm. I call MyForm from MainForm as follows:
#include "MyForm.h" public ref class MainForm : public System::Windows::Forms::Form { ... private:void Caller() { MyForm^ frm = gcnew MyForm(); frm->Show(); } ... }
where MyForm is defined as follows:
But when I run the code, sometimes I get that exception ("read or write from protected memory") or other exceptions on ob->Invoke(ob->myDelegate). But what is wrong? Thanks,public ref class MyForm : public System::Windows::Forms::Form { public: delegate void Del(); Del^ myDelegate; Thread^ oThread; private: System::Void MyForm_Load(System::Object^ sender, System::EventArgs^ e) { myDelegate = gcnew Del(this, &MyForm::Func2); oThread = gcnew Thread(gcnew ParameterizedThreadStart(ThreadProc)); oThread->Start(); } <br/> private: void Func2() { ... } private: static void ThreadProc(System::Object ^obj) { MyForm ^ob = (MyForm^) obj; for(;;) { ob->Invoke(ob->myDelegate); Thread::Sleep(50); } } };
Wednesday, July 14, 2010 6:09 AM -
Hi RedHat,
oThread = gcnew Thread(gcnew ParameterizedThreadStart(ThreadProc));
oThread->Start();
The function ThreadProc is a static function in class MyForm. Therefore when we create the thread, we should use MyForm::ThreadProc.
The function ThreadProc has a parameter which is obj. When we start thread using this function, we should pass the object to the function. In this case, it should be form self.
As a suggestion the above code should be rewritten as :
oThread = gcnew Thread(gcnew ParameterizedThreadStart(MyForm::ThreadProc)); oThread->Start(this);
Cheers,
Yi
Please remember to mark the replies as answers if they help and unmark them if they provide no help.
Welcome to the All-In-One Code Framework! If you have any feedback, please tell us.- Marked as answer by Yi Feng Li Monday, July 19, 2010 1:49 AM
- Unmarked as answer by RedHat_Doom Monday, July 19, 2010 2:10 AM
Wednesday, July 14, 2010 6:42 AM -
Thanks Yi,
I applied what you suggested but still I keep getting that exception (Attempted to read or write protected memory) on
ob->Invoke(ob->myDelegate);
It is so weird! Should I always use "static" for ThreadProc? If so, why? I guess the problem is related to
MyForm ^ob = (MyForm^) obj;
But what do you think? Any new idea? Thanks,
Monday, July 19, 2010 2:13 AM -
Hi RedHat,
Can you post some your modified code in detail ?
Can you exam the value of ob or obj before the for statment? Does it have the valid form object?
Cheers,
Yi
Please remember to mark the replies as answers if they help and unmark them if they provide no help.
Welcome to the All-In-One Code Framework! If you have any feedback, please tell us.Monday, July 19, 2010 3:30 AM -
Hi Yi,
I put a breakpoint on Myform^ ob = (MyForm^) obj and then I ran the code. I get a pointer for obj and when I put the cursor on "obj", the debuger shows me a window with this info: [MyProject::MyForm^] 0x06b5b3bc{oThread=0x06b5b4f8.....}
BTW, the edited code is this:
#include "MyForm.h" public ref class MainForm : public System::Windows::Forms::Form
{
...
private :void Caller()
{
MyForm^ frm = gcnew MyForm();
frm->Show();
}
...
}
public ref class MyForm : public System::Windows::Forms::Form { public: delegate void Del(); Del^ myDelegate; Thread^ oThread; private: System::Void MyForm_Load(System::Object^ sender, System::EventArgs^ e) { myDelegate = gcnewDel(this, &MyForm::Func2); oThread = gcnew Thread(gcnew ParameterizedThreadStart(MyForm::ThreadProc)); oThread->Start(this); } private: void Func2() { Func3(); } private: void Func3() { ... } private: static void ThreadProc(System::Object ^obj) { MyForm ^ob = (MyForm^) obj; for(;;)
{ ob->Invoke(ob->myDelegate); Thread::Sleep(50); } } };
Monday, July 19, 2010 3:45 AM -
Hi Yi,
I just found a problem in Func3. I disabled Func3 and the problem was solved. But how we can make sure that such an exception will not happen in the future? because as you know, such exceptions are raised by chance.
Interesting is that I get the exception at a high level (on ob->invoke(ob->myDelegate)) not at Func3. Also, the callstack window doesn't show Func3! But is there any way to find out in which function the exception is raised?
Thanks,
Monday, July 19, 2010 5:30 AM -
Your code looks fine for me. When you set a break point for Myform^ ob = (MyForm^) obj, and hit the break point, you can step into codes step by step to check which code leads the exception.
In addition, static is not required for creating a thread, if we remove the static, and using “this” instead of ob/obj, does it work?
Cheers,
Yi
Please remember to mark the replies as answers if they help and unmark them if they provide no help.
Welcome to the All-In-One Code Framework! If you have any feedback, please tell us.Monday, July 19, 2010 5:41 AM -
I tried that but I got a compiling error here:
oThread = gcnew Thread(gcnew ParameterizedThreadStart(MyForm::ThreadProc));
The error is this:
'MyProject::MyForm::ThreadProc': function call missing argument list; use '&MyProject::MyForm::ThreadProc' to create a pointer to member
Then I used &MyProject::MyForm::ThreadProc but this time I got this error:
'void MyProject::MyForm::ThreadProc(System::Object ^)' : the specified function does not match the delegate type 'void (System::Object ^)'
Monday, July 19, 2010 5:49 AM -
Hi RedHat,
'MyProject::MyForm::ThreadProc': function call missing argument list; use '&MyProject::MyForm::ThreadProc' to create a pointer to member
This is because when we remove the static, the scope of ThreadProc changes. We can just call like following:
oThread = gcnew Thread(gcnew ParameterizedThreadStart(ThreadProc));
I just found a problem in Func3. I disabled Func3 and the problem was solved. But how we can make sure that such an exception will not happen in the future? because as you know, such exceptions are raised by chance.
Interesting is that I get the exception at a high level (on ob->invoke(ob->myDelegate)) not at Func3. Also, the callstack window doesn't show Func3! But is there any way to find out in which function the exception is raised?
Is there any relationship between func2 and func3? This kind of exception needs to debug case by case, therefore it is hard to tell you how to avoid it in the future.
Cheers,
Yi
Please remember to mark the replies as answers if they help and unmark them if they provide no help.
Welcome to the All-In-One Code Framework! If you have any feedback, please tell us.Monday, July 19, 2010 6:26 AM -
Func2 just call Func3 and that's it. So what code do you suggest me if I remove the static keyword? Thanks!Monday, July 19, 2010 6:45 AM
-
Hi RedHat,
A static member belongs to the type itself rather than to a specific object. The static modifier can be used with classes, fields, methods, properties, operators, events, and constructors, but it cannot be used with indexers, destructors, or types other than classes.
You can see the scope is different. I suggest you try to remove the “static” to see if the scope leads this issue. For example:
private: System::Void MyForm_Load(System::Object^ sender, System::EventArgs^ e) { myDelegate = gcnewDel(this, &Func2); oThread = gcnew Thread(gcnew ParameterizedThreadStart(ThreadProc)); oThread->Start(); } private: void Func2() { Func3(); } private: void Func3() { ... } private: static void ThreadProc(System::Object ^obj) { // MyForm ^ob = (MyForm^) obj; for(;;)<br/> { //ob->Invoke(ob->myDelegate); Invoke(myDelegate); Thread::Sleep(50); } } };
Cheers,
Yi
Please remember to mark the replies as answers if they help and unmark them if they provide no help.
Welcome to the All-In-One Code Framework! If you have any feedback, please tell us.Monday, July 19, 2010 7:35 AM -
I applied what you suggested but I got a lot of compiling errors...I think I'd better use the static keyword.Monday, July 19, 2010 8:12 PM
-
If you're getting compiler errors when not using static, it means your syntax for creating the delegate is wrong. Show what you tried.Monday, July 19, 2010 8:15 PM
-
I used this code:
private: System::Void MyForm_Load(System::Object^ sender, System::EventArgs^ e) { myDelegate = gcnewDel(this, &Func2); oThread = gcnew Thread(gcnew ParameterizedThreadStart(ThreadProc)); oThread->Start(); } private: void Func2() { Func3(); } private: void Func3() { ... } private: static void ThreadProc(System::Object ^obj) { // MyForm ^ob = (MyForm^) obj; for(;;) { //ob->Invoke(ob->myDelegate); Invoke(myDelegate); Thread::Sleep(50); } } };
The first error is the following for "myDelegate = gcnew Del(this, &Func2);":
'&' : illegal operation on bound member function expression
BTW, I used this:
delegate void Del;
Del^ myDelegate;
Monday, July 19, 2010 8:21 PM -
That should be &MyForm::Func2. &Func2 would be to take the address of a free function.Monday, July 19, 2010 8:52 PM
-
Thanks, now I get this error:
'MyProject::MyForm::ThreadProc': function call missing argument list; use '&MyProject::MyForm::ThreadProc' to create a pointer to member
Then I used &MyForm::ThreadProc but this time I got this error:
'void MyProject::MyForm::ThreadProc(System::Object ^)' : the specified function does not match the delegate type 'void (System::Object ^)'
Monday, July 19, 2010 9:00 PM -
Are you implying you removed the 'static' from ThreadProc's definition?Monday, July 19, 2010 9:03 PM
-
Yes, as Yi suggested, I removed static from ThreadProc's definition to check the issue of the scope.Monday, July 19, 2010 9:13 PM
-
Then you need to do 'gcnew ParameterizedThreadStart(this, &MyForm::ThreadProc)', similarly to how you're doing Func2.Monday, July 19, 2010 9:16 PM
-
I did but as I explained above, I got a new error:
'void MyProject::MyForm::ThreadProc(System::Object ^)' : the specified function does not match the delegate type 'void (System::Object ^)'
Monday, July 19, 2010 9:18 PM -
That error doesn't make any sense. Show your actual code.Monday, July 19, 2010 9:22 PM
-
My actual code is as above.Monday, July 19, 2010 9:25 PM
-
The code above shows ThreadProc as being static, and has blatant typos such as 'gcnewDel'. This code wouldn't compile to begin with, so is obviously not your actual code.Monday, July 19, 2010 9:26 PM
-
Here you are:
private: System::Void MyForm_Load(System::Object^ sender, System::EventArgs^ e) { myDelegate = gcnew Del(this, &MyForm::Func2); oThread = gcnew Thread(gcnew ParameterizedThreadStart(&MyForm::ThreadProc)); oThread->Start(); } private: void Func2() { Func3(); } private: void Func3() { ... } private: void ThreadProc(System::Object ^obj) { for(;;) { Invoke(myDelegate); Thread::Sleep(50); } } };
Monday, July 19, 2010 9:29 PM -
Then you need to do 'gcnew ParameterizedThreadStart(this, &MyForm::ThreadProc)', similarly to how you're doing Func2.
You still have 'gcnew ParameterizedThreadStart(&MyForm::ThreadProc)'.- Marked as answer by RedHat_Doom Wednesday, July 21, 2010 12:47 AM
Monday, July 19, 2010 9:33 PM -
OK, now I can compile the program without error. But I still get that exception (attempted to read or write from protected memory). So, it means that it is not related to the scope issue.Monday, July 19, 2010 9:37 PM