How to create an array of delegates using managed C++? (within aWindows Form class)

  • Thread starter David K in San Jose
  • Start date
D

David K in San Jose

I'm using managed (CLR) C++ in VS2005 to create a Windows app that contains a form named "MyForm". In the code for that
form I'm trying to invoke some static functions by using an array of function pointers (delegates). I assume I need to
use the array< T > keyword to allocate an array of delegates, and then initialize the array by setting each array
element to the pointers (handles) of the functions I'll be invoking.

I've been trying to figure this out for several hours, and can't find any examples of how to create and initialize an
array of function delegates in managed C++. I'm hoping someone can post a tiny example that actually works. :)

Below is an example of what I'm trying to do. I want to be able to invoke the functions TestFunc1(), TestFunc2() and
TestFunc3() through an array of delegates to those functions. In the example, I show that I'm able to create a single
delegate TestFunc that points at TestFunc1(), but when I try to create an array of delegates, I get compiler errors
shown in the comments below:

- - Start of code excerpt - - - - -

using namespace System;
using namespace System::ComponentModel;
using namespace System::Collections;
using namespace System::Windows::Forms;
using namespace System::Data;
using namespace System::Drawing;

namespace MyApp {

public ref class MyForm : public System::Windows::Forms::Form
{

// ...snip... Designer-created initialization code for the Windows Form

private:

// Declare the delegate to a test function that takes two integers and returns nothing:
delegate void TestFuncDelegate (int x, int y);

// As a demonstration, instantiate one delegate to TestFunc1():
// (This compiles correctly.)
static TestFuncDelegate ^TestFunc = gcnew TestFuncDelegate( TestFunc1 );

// Now try to instantiate an array of three delegates to TestFunc1(), TestFunc2()
// and TestFunc3():
//
// At compile time, this gives error C3374 and three error C2440s:
// error C3374: can't take address of 'MyApp::MyForm::TestFunc1' unless creating delegate instance
// error C2440: 'initializing' : cannot convert from 'void (__clrcall*)(int,int)' to
MyApp::MyForm::TestFuncDelegate ^'
//
static array<TestFuncDelegate ^> ^TestFuncArray = gcnew array<TestFuncDelegate ^> {
TestFunc1,
TestFunc2,
TestFunc3
};

// Define the three functions we'll call using the delegate:
static void TestFunc1( int x, int y) { return; }
static void TestFunc2( int x, int y) { return; }
static void TestFunc3( int x, int y) { return; }

// ...snip...

} // class Charting
} // namespace MyApp
- - End of code excerpt - - - - -

So I get the error "can't take address of 'TestFunc1' unless creating delegate instance". Maybe I'm wrong in trying to
use the array<> keyword? Or do I have some dereferencing error?

As a 2nd attempt, I'm able to successfully allocate an array of delegates this way:

static array<TestFuncDelegate ^> ^TestFuncArray = gcnew array<TestFuncDelegate ^>(3);

....but I can't figure out how to initialize the TestFuncArray[] at run-time. When I try something like this in the
initialization code for my form:

TestFuncArray[0] = &TestFunc1;

....I get these two compiler errors:

error C3867: 'MyApp::MyChart::TestFunc1': function call missing argument list; use '&MyApp::MyForm::TestFunc1' to
create a pointer to member
error C2440: '=' : cannot convert from 'void (__clrcall MyApp::MyForm::* )(int,int)' to
'MyApp::MyForm::TestFuncDelegate ^'

Any help is appreciated,

David K in San Jose
 
D

David K in San Jose

Sorry, I made a minor screw-up in my posted example; below is a correction. (I had changed the names of my namespace and
class for the posting).

Near the end of my post, I had written:
...I get these two compiler errors:

error C3867: 'MyApp::MyChart::TestFunc1': function call missing
argument list; use '&MyApp::MyForm::TestFunc1' to create a pointer to
member
error C2440: '=' : cannot convert from 'void (__clrcall
MyApp::MyForm::* )(int,int)' to 'MyApp::MyForm::TestFuncDelegate ^'

Any help is appreciated,

The first error message should have said, "MyApp::MyForm", not "MyApp::MyChart". The corrected error msg is:

error C3867: 'MyApp::MyForm::TestFunc1': function call missing argument list; use '&MyApp::MyForm::TestFunc1' to
create a pointer to member

Thanks,

David K in San Jose
 
D

David K in San Jose

Problem fixed! I refused to give up, read some online C++/CLI tutorials (!), and figured out what I was doing wrong. I
was incorrectly instantiating the delegate array elements by not using the gcnew keyword.

For any other C++/CLI (i.e. "managed C++") newbies out there, here's the way I got the array of delegates initialized
properly:

In my original attempt, I was using this to instantiate the elements in my array of delegates:

static array<TestFuncDelegate ^> ^TestFuncArray = gcnew array<TestFuncDelegate ^> {
TestFunc1,
TestFunc2,
TestFunc3
};

But I should have had this:

static array<TestFuncDelegate ^> ^TestFuncArray = gcnew array<TestFuncDelegate ^> {
gcnew TestFuncDelegate(TestFunc1),
gcnew TestFuncDelegate(TestFunc2),
gcnew TestFuncDelegate(TestFunc3)
};


....So now the error messages I was getting made perfect sense, but I was too green to understand how to fix the problem
until I studied up on managed arrays<> and delegates. :)

Thanks to any of those who started to look into this for me.

David K in San Jose
 
B

Ben Voigt [C++ MVP]

David said:
Problem fixed! I refused to give up, read some online C++/CLI
tutorials (!), and figured out what I was doing wrong. I was
incorrectly instantiating the delegate array elements by not using
the gcnew keyword.
For any other C++/CLI (i.e. "managed C++") newbies out there, here's
the way I got the array of delegates initialized properly:

In my original attempt, I was using this to instantiate the elements
in my array of delegates:
static array<TestFuncDelegate ^> ^TestFuncArray = gcnew
array<TestFuncDelegate ^> { TestFunc1,
TestFunc2,
TestFunc3
};

But I should have had this:

static array<TestFuncDelegate ^> ^TestFuncArray = gcnew
array<TestFuncDelegate ^> { gcnew TestFuncDelegate(TestFunc1),
gcnew TestFuncDelegate(TestFunc2),
gcnew TestFuncDelegate(TestFunc3)
};


...So now the error messages I was getting made perfect sense, but I
was too green to understand how to fix the problem until I studied up
on managed arrays<> and delegates. :)

Yup. There's no implicit conversion from the name of a function to a
delegate type in C++ (there is in C# though), so you have to explicitly
write each constructor call.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top