public interface class causes error

T

TBass

I'm trying to put together the plugin framework example from MSDN.

I made a new class library in VS 2003, and created this header file:

#pragma once
#include <string>
#using <mscorlib.dll>


using namespace System;

public interface class IPluginContext
{
string *CurrentDocumentText{get;set;}
};


public interface class IPlugin
{
string *Name{get;}
void PerformAction(IPluginContext context);
};


But I get a compiler error, and I don't know why:
c:\srcroot\Fusion\R-01\FusionDVR\FusionDVR\FusionDVR.h(19): error
C2059: syntax error : 'public'


Why would it be a syntax error? Note: I have added the /CLR compiler
switch.

Can anyone shed some light on my stupidity?

Thanks!
Tom
 
B

Ben Voigt [C++ MVP]

TBass said:
I'm trying to put together the plugin framework example from MSDN.

I made a new class library in VS 2003, and created this header file:

#pragma once
#include <string>
#using <mscorlib.dll>


using namespace System;

public interface class IPluginContext
{
string *CurrentDocumentText{get;set;}
};


public interface class IPlugin
{
string *Name{get;}
void PerformAction(IPluginContext context);
};


But I get a compiler error, and I don't know why:
c:\srcroot\Fusion\R-01\FusionDVR\FusionDVR\FusionDVR.h(19): error
C2059: syntax error : 'public'


Why would it be a syntax error? Note: I have added the /CLR compiler
switch.

Can anyone shed some light on my stupidity?

It looks like you're using the sample code for VS2005 (VC++ 8.0) but
compiling with VC++ 7.1. VC++ managed code support is now universally
recognized as a complete failure and you should start using the newer
version (VC++ 9.0, available as a free download) as soon as you can.
 
T

TBass

It looks like you're using the sample code for VS2005 (VC++ 8.0) but
compiling with VC++ 7.1. VC++ managed code support is now universally
recognized as a complete failure and you should start using the newer
version (VC++ 9.0, available as a free download) as soon as you can.

So I have no way of writing a .NET plugin in VC++ .NET 2003?
 
B

Ben Voigt [C++ MVP]

I meant to say VC++ 7.0/7.1 (Visual Studio 2002 or 2003) managed code
support is recognized as a complete failure. The problems are fixed in VC++
8.0/9.0 (Visual Studio 2005 or 2008).
So I have no way of writing a .NET plugin in VC++ .NET 2003?

Can you provide a link to the sample you are trying to make work?

There's always C#.

What do you think you would gain by using 2003?

I'm also very concerned about your attempt to mix std::string and managed
types. Don't do that. Use only System::String in public .NET interfaces.
 
T

TBass

Can you provide a link to the sample you are trying to make work?

This is the main example:
http://msdn2.microsoft.com/en-us/library/ms972962.aspx


Yes, that seems to be working out better, at least in terms of making
the plugin.

Then I tried (since it was already written), loading in the plugin to
a .NET VC++

This is the code I've been using the "find" plugins by examing the
interfaces of DLLs in a certain directory. I'm looking for the IPlugin
interface (as seen in the example I linked above):

/*
* ::ExamineAssembly
* Is this a Fusion plugin. Let's find out. Add it to the
* plugin list if so.
*/
void
FusionPLG::ExamineAssembly( Assembly *objDLL, char *szInterface )
{
/* Obtain a reference to a method known to exist in assembly */
Type *tmi[] = objDLL->GetTypes();
Type *objType;
Type *objInterface;
int index;
FusionPlugin *fusplug;


for( index=0;index<tmi->Length;index++ )
{

objType = tmi[index]->GetType();

/* WE ONLY LOOK AT PUBLIC TYPES */
if ( objType->IsPublic ) /* PROBLEM <=== ALWAYS FALSE */
{

/* IGNORE ABSTRACT CLASSES */
if ( (objType->Attributes & TypeAttributes::Abstract ) !=
TypeAttributes::Abstract )
{

/* FOR DEBUGGING:: DISPLAY ALL AVAILABLE INTERFACES */
/*
PROBLEM: WE DON'T SEE THE IPLUGIN INTERFACE */

Type *interfaces[] = objType->GetInterfaces();
int x;
for( x=0;x<interfaces->Length;x++ )
{
MessageBox::Show(interfaces[x]->ToString() );
}

/* DOES THIS PLUGIN IMPLEMENT OUR INTERFACE? */
objInterface = objType->GetInterface(szInterface, true );
if ( objInterface != NULL )
{
/* IT DOES. WELCOME TO THE FAMILY. */
std::string mystring;
fusplug = new FusionPlugin;

ManagedToSTL( &mystring, objDLL->Location->ToString() );
fusplug->AssemblyPath( (char *)mystring.c_str() );

ManagedToSTL( &mystring, objType->FullName );
fusplug->ClassName( (char *)mystring.c_str() );

/* PUSH THIS BABY ON THE LIST */
m_listPlugins.push_back( fusplug );

} /* if objInterface */

} /* if objType->Attributes */

} /* if objType->IsPublic */

} /* for */

} /* ::ExamineAssembly */


This is failing on 2 levels. First, the object type is never coming
back public. I commented that out so I could display every interface
available in the DLL. The IPlugin interface never shows up.

Is this part of that failing you were talking about? Or am I just flat
out doing something wrong?

I'm also very concerned about your attempt to mix std::string and managed
types. Don't do that. Use only System::String in public .NET interfaces.

Ok.
 
B

Ben Voigt [C++ MVP]

TBass said:
This is the main example:
http://msdn2.microsoft.com/en-us/library/ms972962.aspx



Yes, that seems to be working out better, at least in terms of making
the plugin.

Could you show the C# code? At least the skeleton, method bodies don't seem
relevant.

Also, when you copy and paste code from Visual Studio, paste into Notepad
first and copy from there into the e-mail editor, that way indentation will
be preserved.
Then I tried (since it was already written), loading in the plugin to
a .NET VC++

This is the code I've been using the "find" plugins by examing the
interfaces of DLLs in a certain directory. I'm looking for the IPlugin
interface (as seen in the example I linked above):

/*
* ::ExamineAssembly
* Is this a Fusion plugin. Let's find out. Add it to the
* plugin list if so.
*/
void
FusionPLG::ExamineAssembly( Assembly *objDLL, char *szInterface )
{
/* Obtain a reference to a method known to exist in assembly */
Type *tmi[] = objDLL->GetTypes();
Type *objType;
Type *objInterface;
int index;
FusionPlugin *fusplug;


for( index=0;index<tmi->Length;index++ )
{

objType = tmi[index]->GetType();

/* WE ONLY LOOK AT PUBLIC TYPES */
if ( objType->IsPublic ) /* PROBLEM <=== ALWAYS FALSE */
{

/* IGNORE ABSTRACT CLASSES */
if ( (objType->Attributes & TypeAttributes::Abstract ) !=
TypeAttributes::Abstract )
{

/* FOR DEBUGGING:: DISPLAY ALL AVAILABLE INTERFACES */
/*
PROBLEM: WE DON'T SEE THE IPLUGIN INTERFACE */

Type *interfaces[] = objType->GetInterfaces();
int x;
for( x=0;x<interfaces->Length;x++ )
{
MessageBox::Show(interfaces[x]->ToString() );
}

/* DOES THIS PLUGIN IMPLEMENT OUR INTERFACE? */
objInterface = objType->GetInterface(szInterface, true );
if ( objInterface != NULL )
{
/* IT DOES. WELCOME TO THE FAMILY. */
std::string mystring;
fusplug = new FusionPlugin;

ManagedToSTL( &mystring, objDLL->Location->ToString() );
fusplug->AssemblyPath( (char *)mystring.c_str() );

ManagedToSTL( &mystring, objType->FullName );
fusplug->ClassName( (char *)mystring.c_str() );

/* PUSH THIS BABY ON THE LIST */
m_listPlugins.push_back( fusplug );

} /* if objInterface */

} /* if objType->Attributes */

} /* if objType->IsPublic */

} /* for */

} /* ::ExamineAssembly */


This is failing on 2 levels. First, the object type is never coming
back public. I commented that out so I could display every interface
available in the DLL. The IPlugin interface never shows up.

Is this part of that failing you were talking about? Or am I just flat
out doing something wrong?

I'm also very concerned about your attempt to mix std::string and managed
types. Don't do that. Use only System::String in public .NET
interfaces.

Ok.
 
T

TBass

.
Could you show the C# code?  At least the skeleton, method bodies don't seem
relevant.

You can have the whole thing. I had to ditch C# because of the SDK I
have to use in the main program. I have to use C++.

Anyway, here's the plugin framework in c#:

using System;

namespace Fusion.Plugins
{
/// <summary>
/// A public interface used to pass context to plugins
/// </summary>
public interface IPluginContext
{
string DeviceName{get;set;}
}
}




using System;

namespace Fusion.Plugins
{
/// <summary>
/// A public interface to be used by all custom plugins
/// </summary>
public interface IPlugin
{
string Name{get;}
void PerformAction(IPluginContext context);
}
}



And then I make the plugin in another project:

using System;
using System.Text.RegularExpressions;
using System.Text;
using Fusion.Plugins;


namespace Fusion.Plugins.Custom
{

public class netModTCP:IPlugin
{
public netModTCP()
{
//
// TODO: Add constructor logic here
//
}

#region IPlugin Members

public void PerformAction(IPluginContext context)
{
frmAbout myfrm = new frmAbout( context.DeviceName );

}

// The name of the plugin as it will appear
// under the editor's "Plugins" menu
public string Name
{
get
{
return "Modbus TCP Plugin";
}
}

#endregion

}
}


Then, which you've seen before, I try and load the plugin from the VC+
+ Class. Unfortunately, the public interfaces I made in the plugin
seem invisible to the VC++. I'm switching it over to a managed class
to see if that works better (before it was native):


/*
* ::ExamineAssembly
* Is this a Fusion plugin. Let's find out. Add it to the
* plugin list if so.
*/
void
FusionPLG::ExamineAssembly( Assembly *objDLL, String *szInterface )
{
/* Obtain a reference to a method known to exist in assembly */
Type *tmi[] = objDLL->GetTypes();
Type *objType;
Type *objInterface;
int index;
FusionPlugin *fusplug;


for( index=0;index<tmi->Length;index++ )
{

objType = tmi[index]->GetType();

/* WE ONLY LOOK AT PUBLIC TYPES */
if ( objType->IsPublic )
{

/* IGNORE ABSTRACT CLASSES */
if ( (objType->Attributes & TypeAttributes::Abstract ) !=
TypeAttributes::Abstract )
{

/* FOR DEBUGGING:: DISPLAY ALL AVAILABLE INTERFACES */
Type *interfaces[] = objType->GetInterfaces();
int x;
for( x=0;x<interfaces->Length;x++ )
{
MessageBox::Show(interfaces[x]->ToString() );
}

/* DOES THIS PLUGIN IMPLEMENT OUR INTERFACE? */
objInterface = objType->GetInterface(szInterface, true );
if ( objInterface != NULL )
{
/* IT DOES. WELCOME TO THE FAMILY. */
fusplug->AssemblyPath( objDLL->Location->ToString() );
fusplug->ClassName( objType->FullName );

/* PUSH THIS BABY ON THE LIST */
m_listPlugins->Add( fusplug );

} /* if objInterface */

} /* if objType->Attributes */

} /* if objType->IsPublic */

} /* for */

} /* ::ExamineAssembly */
 
T

TBass

compiling with VC++ 7.1.  VC++ managed code support is now universally
recognized as a complete failure and you should start using the newer
version (VC++ 9.0, available as a free download) as soon as you can.

I wanted to get some clarification on this point :: do mean that
Manged VC++ on 7.1 thru 8.0 just plain doesn't work? Or is it the
integration between managed c++ and native? What was the problem?

What's different about 9.0?

Thanks!
T
 
C

Carl Daniel [VC++ MVP]

TBass said:
I wanted to get some clarification on this point :: do mean that
Manged VC++ on 7.1 thru 8.0 just plain doesn't work? Or is it the
integration between managed c++ and native? What was the problem?

The "Managed Extensions for C++" syntax that was introduced with VC7 has a
lot of problems and has been deprecated - at some point, it will be removed
from the product. VC8 (2005) introduced "C++/CLI", which is the
going-forward solution for managed C++ development.
What's different about 9.0?

AFIAK, nothing in this regard. There are some new C++/CLI libraries
(STL/CLR and the marshalling library), but the code language is unchanged.

-cd
 
B

Ben Voigt [C++ MVP]

7.0 and 7.1 are broken, deadlocking randomly on startup.

8.0 is fixed, and 9.0 takes care of some unrelated bugs.

TBass said:
compiling with VC++ 7.1. VC++ managed code support is now universally
recognized as a complete failure and you should start using the newer
version (VC++ 9.0, available as a free download) as soon as you can.

I wanted to get some clarification on this point :: do mean that
Manged VC++ on 7.1 thru 8.0 just plain doesn't work? Or is it the
integration between managed c++ and native? What was the problem?

What's different about 9.0?

Thanks!
T
 
B

Ben Voigt [C++ MVP]

TBass said:
This is the main example:
http://msdn2.microsoft.com/en-us/library/ms972962.aspx



Yes, that seems to be working out better, at least in terms of making
the plugin.

Then I tried (since it was already written), loading in the plugin to
a .NET VC++

This is the code I've been using the "find" plugins by examing the
interfaces of DLLs in a certain directory. I'm looking for the IPlugin
interface (as seen in the example I linked above):

Sorry about the irrelevant question. I spotted your problem.
/*
* ::ExamineAssembly
* Is this a Fusion plugin. Let's find out. Add it to the
* plugin list if so.
*/
void
FusionPLG::ExamineAssembly( Assembly *objDLL, char *szInterface )
{
/* Obtain a reference to a method known to exist in assembly */
Type *tmi[] = objDLL->GetTypes();
Type *objType;
Type *objInterface;
int index;
FusionPlugin *fusplug;


for( index=0;index<tmi->Length;index++ )
{

objType = tmi[index]->GetType();

Wrong. tmi[index] is already a System::Type, so your code sets objType =
System::Type::typeid, and of course none of your interfaces are present.

You want

objType = tmi[index];

Or better yet, use a for each loop because you don't care about the index.
/* WE ONLY LOOK AT PUBLIC TYPES */
if ( objType->IsPublic ) /* PROBLEM <=== ALWAYS FALSE */
{

Ok, I lied. tmi[index] is a private concrete class derived from
System::Type (which is abstract).
/* IGNORE ABSTRACT CLASSES */
if ( (objType->Attributes & TypeAttributes::Abstract ) !=
TypeAttributes::Abstract )
{

/* FOR DEBUGGING:: DISPLAY ALL AVAILABLE INTERFACES */
/*
PROBLEM: WE DON'T SEE THE IPLUGIN INTERFACE */

Type *interfaces[] = objType->GetInterfaces();
int x;
for( x=0;x<interfaces->Length;x++ )
{
MessageBox::Show(interfaces[x]->ToString() );
}

/* DOES THIS PLUGIN IMPLEMENT OUR INTERFACE? */
objInterface = objType->GetInterface(szInterface, true );
if ( objInterface != NULL )
{
/* IT DOES. WELCOME TO THE FAMILY. */
std::string mystring;
fusplug = new FusionPlugin;

ManagedToSTL( &mystring, objDLL->Location->ToString() );
fusplug->AssemblyPath( (char *)mystring.c_str() );

ManagedToSTL( &mystring, objType->FullName );
fusplug->ClassName( (char *)mystring.c_str() );

/* PUSH THIS BABY ON THE LIST */
m_listPlugins.push_back( fusplug );

} /* if objInterface */

} /* if objType->Attributes */

} /* if objType->IsPublic */

} /* for */

} /* ::ExamineAssembly */


This is failing on 2 levels. First, the object type is never coming
back public. I commented that out so I could display every interface
available in the DLL. The IPlugin interface never shows up.

Is this part of that failing you were talking about? Or am I just flat
out doing something wrong?

I'm also very concerned about your attempt to mix std::string and managed
types. Don't do that. Use only System::String in public .NET
interfaces.

Ok.
 

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