Problem with event declaration - possible VS.NET bug?

W

Wild Wind

Hello,

I made a post relating to this issue a while
back, but I haven't received any answer, so
here I am again.

I am writing a mixed C++ dll which uses the following
declaration:

typedef System::Byte ByteArray __gc[];

Then I have an event declared in the main class
for the dll as follows:

__event void MyEvent(ByteArray* ba);

The problem is that with this event declaration, when
I compile the code, I get the following errors:

error C2059: syntax error : ')'
error C2143: syntax error : missing ')' before ';'
error C2629: unexpected 'unsigned char ('

Each error is shown thrice.

My suspicions are that when you have __event
declarations for events that take pointers to
managed arrays, these expand to code which has
a syntax error. I tried this for a pointer to
an array of Strings and I was getting the same
kind of errors.

Also, when I modified the event declaration to

__event void MyEvent(ByteArray ba);

the errors went away.

Is this an MS bug? Can anyone reproduce this?
If it is a problem, is there anyway I can still
declare the event I want to?

TIA,
 
B

Brandon Bray [MSFT]

Wild said:
The problem is that with this event declaration, when
I compile the code, I get the following errors:

error C2059: syntax error : ')'
error C2143: syntax error : missing ')' before ';'
error C2629: unexpected 'unsigned char ('

Each error is shown thrice.

I was able to reproduce this. With the VC2005 40901 compiler, a different
error message is shown:

t.cpp(6) : error C2697: 'i1' : must explicitly specify __gc or __nogc for an
array declared in a managed type
t.cpp(6) : error C2664: 'C::__Delegate_MyEvent::Invoke' : cannot convert
parameter 1 from 'unsigned char (*)[1]' to 'unsigned char (*) __gc[]'
Types pointed to are unrelated; conversion requires
reinterpret_cast, C-style cast or function-style cast

Both the VC2003 and VC2005 messages are wrong. There's nothing wrong with
this code. I rewrote it without the typedef as follows:

__event void MyEvent( System::Byte (__nogc*ba)__gc[]);
Also, when I modified the event declaration to

__event void MyEvent(ByteArray ba);

the errors went away.

That is correct. The difference is the code without errors is only passing a
pointer to an array, whereas the code with errors is passing a __nogc
pointer to a __gc pointer to an array. I'm guessing that two levels of
indirection are probably not necessary, so the code without errors is likely
something you can use.
Is this an MS bug? Can anyone reproduce this?
If it is a problem, is there anyway I can still
declare the event I want to?

I do believe this is a bug. You can file this at the link below, but it's
not likely to be fixed. In the new syntax, you need to write the delegate
declaration separately from the event. For example:

delegate void MyDel(array<System::Byte>^* ba);
event MyDel^ MyEvent;

I don't see anyway to workaround the errors above if you really need to pass
a pointer to a pointer to the array. I think the best way is to consider a
different approach.

Sorry for the inconvenience.
 
W

Wild Wind

Brandon Bray said:
Wild said:
The problem is that with this event declaration, when
I compile the code, I get the following errors:

error C2059: syntax error : ')'
error C2143: syntax error : missing ')' before ';'
error C2629: unexpected 'unsigned char ('

Each error is shown thrice.

I was able to reproduce this. With the VC2005 40901 compiler, a different
error message is shown:

t.cpp(6) : error C2697: 'i1' : must explicitly specify __gc or __nogc for an
array declared in a managed type
t.cpp(6) : error C2664: 'C::__Delegate_MyEvent::Invoke' : cannot convert
parameter 1 from 'unsigned char (*)[1]' to 'unsigned char (*) __gc[]'
Types pointed to are unrelated; conversion requires
reinterpret_cast, C-style cast or function-style cast

Both the VC2003 and VC2005 messages are wrong. There's nothing wrong with
this code. I rewrote it without the typedef as follows:

__event void MyEvent( System::Byte (__nogc*ba)__gc[]);
Also, when I modified the event declaration to

__event void MyEvent(ByteArray ba);

the errors went away.

That is correct. The difference is the code without errors is only passing a
pointer to an array, whereas the code with errors is passing a __nogc
pointer to a __gc pointer to an array. I'm guessing that two levels of
indirection are probably not necessary, so the code without errors is likely
something you can use.
Is this an MS bug? Can anyone reproduce this?
If it is a problem, is there anyway I can still
declare the event I want to?

I do believe this is a bug. You can file this at the link below, but it's
not likely to be fixed. In the new syntax, you need to write the delegate
declaration separately from the event. For example:

delegate void MyDel(array<System::Byte>^* ba);
event MyDel^ MyEvent;

I don't see anyway to workaround the errors above if you really need to pass
a pointer to a pointer to the array. I think the best way is to consider a
different approach.

Sorry for the inconvenience.

Hello Brandon,

Thanks for your reply. I will file the bug at the link
you mention below. You are probably right about there
not being a need to have the event delegate taking as
an argument a pointer to an array of System::Byte -
I did that because in the documentation, it speaks of
arrays being objects that must be referenced (presumably
using a pointer).

Interestingly enough, you say

"The difference is the code without errors is only
passing a pointer to an array"

Is that right? When I declare a managed array of an object,
does this mean that in passing the array, I am implicitly
passing a pointer to the array? And does this also apply
for other managed types, like System::String?

One other question - I take it that the syntax changes
you mention are planned for Whidbey, and the caret (hat)
signifies a managed pointer to an object? What is the
significance the asterisk after the caret you have in

delegate void MyDel(array<System::Byte>^* ba);

TIA for any answers.
 
B

Brandon Bray [MSFT]

Wild said:
Interestingly enough, you say

"The difference is the code without errors is only
passing a pointer to an array"

Is that right? When I declare a managed array of an object,
does this mean that in passing the array, I am implicitly
passing a pointer to the array? And does this also apply
for other managed types, like System::String?

That's right. The array syntax is somewhat confusing in this manner. For all
other managed types, the * is required. So, you'll always see a
System::String as 'System::String*'. __gc arrays are really just a pointer
to a garbage collected array -- the syntax just obscures that fact slightly.

A quick way to observe that arrays are actually just __gc pointers being
passed around is to note the conversions between System::Object*. For
example:

Object* F(Object* o) { return o; }

int main() {
int arr1 __gc[] = { 0, 1, 2 };
int arr2 __gc[] = (int __gc[])F(arr1);
}
One other question - I take it that the syntax changes
you mention are planned for Whidbey, and the caret (hat)
signifies a managed pointer to an object? What is the
significance the asterisk after the caret you have in

delegate void MyDel(array<System::Byte>^* ba);

That is a native pointer to a handle. In the new Whidbey syntax, a * always
means '__nogc*' from the old syntax. The hat to the array is making it clear
that you're passing around a handle. That array declaration is how to
express in the new syntax what you were trying to do in the old syntax.

Cheerio!
 

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