C++.net Delegate not working - compiler error - multithreading

Right I created a new thread from a static function from the same class.
Inside the same class I try to call a delegate to update the GUI.
I get a compiler error saying:
Invalid delegate initializer - an object is needed in addition to a function.
At &MainUi::AddListItemMethod.
delegate void AddListItem(void);
public: void AddListItemMethod(String^ myString)
{
ListView1->Items->Add(myString);
}
private: static void SecondThread()
{
AddListItem^ del = gcnew AddListItem(&MainUI::AddListItemMethod);
del->Invoke("test");
}
I don't know why it doesn't work. I also tried this and still failed. Any help please?
Invoke(gcnew AddListItem(MainUI::&AddListItemMethod), "test");

Either You have to make Listview1 static to work or you should create an instance/object of MainUI class to access a non static method of that class.
Thank you and Happy coding.

Related

Calling delegate from (get, set )Properties c#

I need help to use the below piece of code to call Method1. There are no compilation issues but while running the code Method1 is not invoked. I searched the net a lot but didn't find a solution.
public static class Test12
{
public static Test12.ByteDelegate PropertyValue { get; set; }
public delegate byte[] ByteDelegate(byte p1, byte[] p2);
}
The above class has to be used like this:
class Abc
{
internal void Stat()
{
Test12.Propertyvalue = Method1;
}
private byte[] Method1(byte p1, byte[] p2)
{
byte[] abc = ...;
return abc;
}
}
If I am creating an instance of the delegate in stat method and using it like:
Method1(param1,param2);
Then the Method1 in invoked, but if I use it like this:
Test12.PropertyValue = Method1(param1,param2);
compiler is throwing an error saying missing typecast. Can anybody please tell me how to invoke Method1 using Test12.PropertyValue = Method1;?
You receive an error message because when you try to assign the method to the delegate you are using the following line of code:
test12.propertyvalue = method1(param1, param2);
Which firstly calls the method1 and then what it returns it's trying to assign to the delegate, and the error message occurs saying that you can't assign a byte array to a delegate, as #Jon said in the comment. They are different types so you can't assign one to another, at least not without a cast or a conversion method.
In order to invoke the method1 from the delegate, after you do the assignation like this:
test12.propertyvalue = method1;
you can simply call the delegate, as it would be your method:
test12.propertyvalue(param1 , param2);

Calling Overload Methods

I can't seem to make this work let alone compile and I am at loss at how to fix it. My teacher gave us the following code (simplified for question's sake):
public static void doing1(String s) {
// add code here
}
public static void doing2(char start, char end) {
// add code here
}
public static int doing3(int num) {
// add code here
}
public static void doing4(Scanner keyboard) {
// add code here
}
I know what needs to go in each method (the work I mean) I just don't know how to print it out in the main method. We cannot change the code given to us, only add to it.
Thank you!
Overloading a method means having the same method name but the method signature (the parameters passed in) is different. So, what you have isn't actually an overload, it is for unique methods because they all have different names. As far as not compiling... what you posted looks fine - perhaps you have an error above or below that code. I believe this is what you are looking for:
public static void doing(String s) {
// add code here
}
public static void doing(char start, char end) {
// add code here
}
public static int doing(int num) {
// add code here
}
public static void doing(Scanner keyboard) {
// add code here
}
Here's a reference on overloads from the almighty John Skeet

C++ how to change private members of managed object using a native one?

I'm working on a student project. It's a network card game. The solution contains 3 projects. Client's GUI using Windows Forms so it has managed classes. Static client's library in native C++. GUI's project has reference to it thus uses 'Mixed Rules'. Server is in native C++ as well. I use RPC middleware for communication. It works only with native C++. That is why I need the static library to hide there all the details of communication on client's side.
Since the server can at any moment change its state and that should be shown in client's GUI, I use callback approach to change Windows Forms' components. And here I found a problem because I need to change private members of managed class with the help of a native object.
There are probably different ways to do that. My idea is sending a pointer to instance of managed class into instance of native class and saving it there. So later I can call from that native object public member functions of that managed class to change components.
This is from my 'Mixed Rules' GUI project:
//Native class for changing window 'Lobby'
class LobbyI : public ClientLib::Lobby {
public:
LobbyI();
~LobbyI();
//Should change window due to current Server's state
void reDraw(const CommonLogic::ServerState&);
};
// Managed class implements GUI for window 'Lobby'
// generated by Visual Studio designer
public ref class LobbyGUI : public System::Windows::Forms::Form {
//My members
ClientLib::Mediator* mediatorPtr; // Is it correct?
LobbyI* lobbyPtr; // ?
public:
LobbyGUI(void) {
InitializeComponent();
mediatorPtr = new ClientLib::Mediator(); // Is it correct?
lobbyPtr = new LobbyI(); // ?
mediatorPtr->setCallback(lobbyPtr);
}
protected:
~LobbyGUI() {
if (components) { delete components; }
delete lobbyPtr; // Is it correct?
lobbyPtr = nullptr; // ?
delete mediatorPtr; // ?
mediatorPtr = nullptr; // ?
}
private: System::Windows::Forms::Button^ buttonLogIn;
//...
This is from native static library ClientLib:
class Lobby {
public:
virtual ~Lobby();
virtual void reDraw(const CommonLogic::ServerState&) = 0;
};
class Mediator {
CommonLogic::ServerState serverState;
Lobby* lobbyPtr;
public:
Mediator();
~Mediator();
void setCallback(Lobby* ptr) { lobbyPtr = ptr; }
void reDrawLobby() { lobbyPtr->reDraw(serverState); }
};
This code builds ok. The only thing I need now is that the member function reDraw() of native derived class LobbyI is able to change the window implemented by managed class LobbyGUI. Thus getting and keeping and using pointer to it. And then I think it all will work. How to do that?
Maybe it's not the nicest implementation in general. I would be happy to read other suggestion.
I'm also doubtful about the way I used pointers to native classes inside managed class. Is it correct? It didn't work correct until I inserted ptr=nullptr; after delete ptr; in destructor.
UPDATE: Now I see redundancy in my code. Abstract class Lobby is useless. I need only to implement reDraw() function in managed class which will have obviously access to components of the window. And then pass safe pointer to native class function which expects pointer to a function as a parameter.
Finally I've solved it!! Using this article. In the following code a native object stores provided pointer to a function of managed object. So this callback function can be invoked at any time. A delegate is used as a form of type-safe function pointer. Instance of GCHandle is used to prevent the delegate from being relocated by garbage collector.
Here is simple CLR Console Application which increments and prints some integer using callback function invoked from native object. Thus we can "change private members of managed object using a native one".
using namespace System;
using namespace System::Runtime::InteropServices;
typedef void(__stdcall *ANSWERCB)(); // define type of callback function
#pragma unmanaged
class NativeClass {
ANSWERCB cbFuncPtr = 0; // pointer to callback function
public:
void setCallback(ANSWERCB fptr) {
cbFuncPtr = fptr;
incAndPrint();
}
void incAndPrint() { cbFuncPtr(); } // invokes callback which increments and prints
};
#pragma managed
ref class ManagedClass {
public: delegate void Del();
private:
Int32 i;
NativeClass* nativePtr;
Del^ delHandle;
GCHandle gch;
public:
ManagedClass(Int32 ii) : i(ii) {
nativePtr = new NativeClass;
delHandle = gcnew Del(this, &ManagedClass::changeAndPrintInt);
gch = GCHandle::Alloc(delHandle);
IntPtr ip = Marshal::GetFunctionPointerForDelegate(delHandle);
ANSWERCB callbackPtr = static_cast<ANSWERCB>(ip.ToPointer());
nativePtr->setCallback(callbackPtr);
}
~ManagedClass() {
delete nativePtr;
nativePtr = __nullptr;
gch.Free();
}
private:
void changeAndPrintInt() // callback function
{
Console::WriteLine(++i);
}
};
int main(array<System::String ^> ^args)
{
ManagedClass mc(1);
return 0;
}

Android JNI method - Is the second parameter jclass or jobject?

Folks,
In my Android Java code, I have a declaration as follows:
public class SurfacePanelNative extends SurfaceView implements SurfaceHolder.Callback {
...
private static native void native_render();
}
In my native code, I have the function declared as:
void native_render(JNIEnv *env, jobject javaSurface) {
ANativeWindow* window = ANativeWindow_fromSurface(env, javaSurface);
...
}
Looking at some examples on the net, it appears that the function should be declared as:
void native_render(JNIEnv *env, jclass clazz) {
...
}
I am wondering which declaration is the right one.
I am thinking the first one is the right one. Otherwise, I don't have enough information to obtain javaSurface.
I would appreciate it if someone can shed some light on this.
Thank you in advance for your help.
Regards,
Peter
It is jclass if the method is static, otherwise jobject. If you use javah, as the JNI designers intended, you will always get the right answer.

Invoking Delegates from a dispatcher

I've been stuck on this all morning, even though it seems like it should be very easy (wondering if I'm missing something fundamental). I have the following code in a class-
public class myClass
{
private Dispatcher m_Dispatcher;
private void myMethod() { ... }
private void invokeTheMethod(object sender, PropertyChangedEventArgs e)
{
m_Dispatcher.Invoke(myMethod); //XYZ
}
}
The dispatcher is attached to the thread that instance of myClass is running on. The invokeTheMethod method is called from another thread, and I'd like to run myMethod on the thread of m_Dispatcher. However, if I try to run this code, I get an exception at XYZ saying "Object reference not an instance of an object". Is this because I haven't declared myMethod in the form of a delegate? - I have tried different ways to declare myMethod as a delegate, but I can't get any of them to compile. Any suggestions are very much appreciated.
Thanks,
Chris
The error you get
Object reference not an instance of an object (NullReferenceException)
refers to the field m_Dispatcher. It is null. That is why you cannot call the Invoke method on it.
Even if there is an instance of Dispatcher "attached to the thread", there is no way for myClass to get hold of that instance.
What you could do is to supply the instance of Dispatcher to myClass when you create an instance of myClass. Something like this:
public class myClass
{
// Here is the 'injection' of the instance in the constructor of this class
public myClass(Dispatcher dispatcher) {
m_Dispatcher = dispatcher;
}
private Dispatcher m_Dispatcher;
private void myMethod() { ... }
private void invokeTheMethod(object sender, PropertyChangedEventArgs e)
{
m_Dispatcher.Invoke(myMethod); //XYZ
}
}
As a side note, you should read up some on coding conventions as your casing is considered wrong by the majority of the C# development community. Here is a good start: http://msdn.microsoft.com/en-us/library/vstudio/w2a9a9s3.aspx

Resources