[C++/CLI] een C# interface implementeren *

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

  • ThaStealth
  • Registratie: Oktober 2004
  • Laatst online: 11-09 10:19
Voor een project ben ik bezig om een aantal zaken uit te testen. Hetgene wat ik nu aan het uittesten ben is een mogelijkheid verschillende plugins in verschillende talen te ontwikkelen. Het kan dus voorkomen dat een C# plugin gebruikt naast een C++ plugin. Op dit moment ben ik bezig met een C++ plugin die dus een interface implementeert die in een C# project is omschreven. Echter krijg ik de volgende compiler error:

Error 2 error C3766: 'MyFirstMenuItem' must provide an implementation for the interface method 'int Backend::IRootMenuitem::GetItem(void)' ExtensionCreator_2.h 17 ExtensionCreator_2

De ExtensionCreator_2.h omvat de volgende code:

C++:
1
2
3
4
5
6
7
8
public ref class MyFirstMenuItem : IRootMenuitem
    {
        int MyFirstMenuItem::GetItem(void)
        {
            return 0;
        }
        // TODO: Add your methods for this class here.
    };


De IRootMenuItem omvat de volgende code:

C#:
1
2
3
4
5
6
7
namespace Backend
{
    public interface IRootMenuitem : IBase
    {
        int GetItem();
    }
}


Zoals te zien is implementeerd de C++ class de vereiste interface. (Ik begrijp dat ik de implementatie in de .cpp bestand moet zetten, maar aangezien ik de foutmelding kreeg heb ik hem voor het testen even in de .h file gezet).
Op internet kan ik niet veel over dit onderwerp vinden, het meerendeel gaat erover hoe een C# of een C++ interface aangemaakt moet worden of hoe van een C++ naar een C# project geport moet worden.

edit:

Vergeten erbij te vertellen, ik werk in vs2008 en ik heb als C++ project een CLR Class Libary gekozen

[ Voor 4% gewijzigd door ThaStealth op 27-05-2008 16:28 ]

Mess with the best, die like the rest


Acties:
  • 0 Henk 'm!

  • Sebazzz
  • Registratie: September 2006
  • Laatst online: 05:47

Sebazzz

3dp

Kan niet. Sla MSDN er maar op na. Met een een unmanaged taal kan je helaas geen managed library laden (dat is wat je wilt doen toch?). Andersom uiteraard wel.

[Te koop: 3D printers] [Website] Agile tools: [Return: retrospectives] [Pokertime: planning poker]


Acties:
  • 0 Henk 'm!

  • riezebosch
  • Registratie: Oktober 2001
  • Laatst online: 10-09 11:15
Sebazzz schreef op dinsdag 27 mei 2008 @ 16:30:
Kan niet. Sla MSDN er maar op na. Met een een unmanaged taal kan je helaas geen managed library laden (dat is wat je wilt doen toch?). Andersom uiteraard wel.
Er staat toch niet dat hij unmanaged C++ gebruikt?

Canon EOS 400D + 18-55mm F3.5-5.6 + 50mm F1.8 II + 24-105 F4L + 430EX Speedlite + Crumpler Pretty Boy Back Pack


Acties:
  • 0 Henk 'm!

  • bigbeng
  • Registratie: Augustus 2000
  • Laatst online: 26-11-2021
klok, klepel, any1?
Vanuit unmanaged code een managed interface implementeren kan niet, maar dat is de vraag hier niet. C++ is niet automatisch unmanaged, sterker nog, na de laatste edit van de TS is het duidelijk dat hij met managed C++/CLI aan de gang is gegaan. En volgens mij kun je een unmanaged interface ook niet implementeren met managed code.

@TS: Ik heb verder weinig verstand van C++, maar is het een idee om gewoon de syntax te gebruiken zoals hij in de foutmelding wordt gegeven? Het is maar een gok.

[ Voor 1% gewijzigd door bigbeng op 27-05-2008 16:44 . Reden: .oisyn :-( ;-) ]


Acties:
  • 0 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 01:28

.oisyn

Moderator Devschuur®

Demotivational Speaker

Hij heeft het over C++ en de titel zegt ook C++, maar hij bedoelt volgens mij idd gewoon C++/CLI (wat in feite een andere taal is) (en "managed C++" is wéér wat anders en bovendien deprecated - lastig he al die namen :P)

@ThaStealth: waarom typ je "MyFirstMenuItem::" voor de implementatie van die method? Maar de clue is dat het 'virtual' keyword mist bij de implementatie. Iets zegt me trouwens dat je je errors nogal selectief quote, want in mijn testvoorbeeld zet ie dat er gewoon bij:
1>.\main.cpp(10) : warning C4488: 'Ding::test' : requires 'virtual' keyword to implement the interface method 'ITest::test'
1>        A ref class or value class method is never implicitly 'virtual' (even if it matches a virtual method from a base)
1>.\main.cpp(12) : error C3766: 'Ding' must provide an implementation for the interface method 'int ITest::test(void)'
1>        .\main.cpp(5) : see declaration of 'ITest::test'

[ Voor 69% gewijzigd door .oisyn op 27-05-2008 16:47 ]

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Acties:
  • 0 Henk 'm!

  • ThaStealth
  • Registratie: Oktober 2004
  • Laatst online: 11-09 10:19
.oisyn schreef op dinsdag 27 mei 2008 @ 16:39:
Hij heeft het over C++ en de titel zegt ook C++, maar hij bedoelt volgens mij idd gewoon C++/CLI (wat in feite een andere taal is) (en "managed C++" is wéér wat anders en bovendien deprecated - lastig he al die namen :P)

@ThaStealth: waarom typ je "MyFirstMenuItem::" voor de implementatie van die method? Maar de clue is dat het 'virtual' keyword mist bij de implementatie.
Dat was een experiment of het misschien wel zou lukken als ik het ervoor zette (wat jammerlijk genoeg faalde :'(). En je hebt gelijk over het selectief quoten, ik had de warnings tab uit staan en er helemaal niet op gelet :o. Hieronder de warnings die er ook nog bijhoren:

Warning 1 warning C4488: 'MyFirstMenuItem::GetItem' : requires 'virtual' keyword to implement the interface method 'Backend::IRootMenuitem::GetItem' ExtensionCreator_2.h 12 ExtensionCreator_2

Warning 2 warning C4570: 'MyFirstMenuItem' : is not explicitly declared as abstract but has abstract functions ExtensionCreator_2.h 10 ExtensionCreator_2

@Niemand_Anders
Dat maakt geen verschil voor de foutmelding, maar je hebt gelijk het moet weg. Ik had het alleen erneer gezet vanwege de foutmelding

[ Voor 34% gewijzigd door ThaStealth op 27-05-2008 16:52 ]

Mess with the best, die like the rest


Acties:
  • 0 Henk 'm!

  • Niemand_Anders
  • Registratie: Juli 2006
  • Laatst online: 09-07-2024

Niemand_Anders

Dat was ik niet..

Het .NET platform ondersteund niet de mogelijkheid om een void als parameter door te geven aan de methode. In C++ kan void van alles zijn. Op FunctionX is een goede inleiding over C++/CLI en de verschillen met C en C++ te vinden.

Je zult je C++ implementatie moeten aanpassen naar:
C++:
1
2
3
4
5
6
7
public ref class MyFirstMenuItem : IRootMenuitem 
{
    int GetItem()
    {
        return 0;
    }
}


Ik haal zelf ook nog even af en toe C++ en C++/CLI door elkaar.

If it isn't broken, fix it until it is..


Acties:
  • 0 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 01:28

.oisyn

Moderator Devschuur®

Demotivational Speaker

Niemand_Anders schreef op dinsdag 27 mei 2008 @ 16:48:
Het .NET platform ondersteund niet de mogelijkheid om een void als parameter door te geven aan de methode. In C++ kan void van alles zijn.
Zoals wel vaker zit je er wederom faliekant naast. In C en C++ betekent een void parameter namelijk dat er géén parameters zijn. Het verschil tussen C en C++ is in deze dat als je een functie declareert met slechts een haakje openen en sluiten (dus zonder void), dat dat in C betekent dat de parameters ongedefineerd zijn, terwijl in C++ dat betekent dat er geen parameters zijn. Dus in C ben je zelfs verplicht 'void' te gebruiken om aan te geven dat er geen parameters zijn (wat dus compleet het tegenovergestelde betekent van "dat kan vanalles zijn").
Je zult je C++ implementatie moeten aanpassen naar:
C++:
1
2
3
4
5
6
7
public ref class MyFirstMenuItem : IRootMenuitem 
{
    int GetItem()
    {
        return 0;
    }
}
Onzin, wat ie moet doen is GetItem() public maken (nu is ie nog default private), en er virtual voor zetten. Die void mag blijven staan.
ThaStealth schreef op dinsdag 27 mei 2008 @ 16:47:
@Niemand_Anders
Dat maakt geen verschil voor de foutmelding, maar je hebt gelijk het moet weg.
Het moet niet weg, 'void' is perfect valide :). Over je 'MyFirstMenuItem::', in ISO C++ mag dat niet, maar dit is C++/CLI en vziw is MS de enige compiler die die taal als zodanig ondersteunt dus ik zou het niet als "verboten!" willen beschouwen. Toch staat het een beetje raar, en omdat het in ISO C++ niet mag vind ik het persoonlijk netter om het dan ook niet te gebruiken :)

[ Voor 28% gewijzigd door .oisyn op 27-05-2008 17:03 ]

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Acties:
  • 0 Henk 'm!

  • Woy
  • Registratie: April 2000
  • Niet online

Woy

Moderator Devschuur®
Niemand_Anders schreef op dinsdag 27 mei 2008 @ 16:48:
Het .NET platform ondersteund niet de mogelijkheid om een void als parameter door te geven aan de methode. In C++ kan void van alles zijn. Op FunctionX is een goede inleiding over C++/CLI en de verschillen met C en C++ te vinden.
In C++ houd het op deze manier gewoon in dat er geen parameters zijn. Zoals jij het bodoeld is het alleen als je een void pointer krijgt ( void * )

edit:

spuit 11
.oisyn schreef op dinsdag 27 mei 2008 @ 16:53:
Onzin, wat ie moet doen is GetItem() public maken (nu is ie nog default private), en er virtual voor zetten. Die void mag blijven staan.
Dat hij public moet zijn is me logisch, maar waarom zou een interface implementatie virtual moeten zijn?

[ Voor 25% gewijzigd door Woy op 27-05-2008 16:55 ]

“Build a man a fire, and he'll be warm for a day. Set a man on fire, and he'll be warm for the rest of his life.”


Acties:
  • 0 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 01:28

.oisyn

Moderator Devschuur®

Demotivational Speaker

rwb schreef op dinsdag 27 mei 2008 @ 16:53:
Dat hij public moet zijn is me logisch, maar waarom zou een interface implementatie virtual moeten zijn?
Weet ik niet precies. In C++ is het zo dat een method die ooit als virtual is gedefinieerd in een van de baseclasses ook impliciet virtual is in de derived classes. De warning van de compiler ("A ref class or value class method is never implicitly 'virtual' (even if it matches a virtual method from a base") suggereert dat dat voor C++/CLI niet opgaat. Kun je in C# een method weer non-virtual maken (en dan bedoel ik niet sealen)?

.edit: een method met dezelfde naam hoeft natuurlijk ook niet die base method te overriden. Dit kan immers ook:
C++:
1
2
3
4
5
6
7
8
9
10
11
12
13
public ref class MyFirstMenuItem : IRootMenuitem 
{ 
public:
    virtual int CompletelyDifferentName() = IRootMenuitem::GetItem
    { 
        return 0; 
    } 

    int GetItem() // nieuwe GetItem(), niet die uit IRootMenuitem
    {
        return 0;
    }
};

[ Voor 34% gewijzigd door .oisyn op 27-05-2008 17:08 ]

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Acties:
  • 0 Henk 'm!

  • ThaStealth
  • Registratie: Oktober 2004
  • Laatst online: 11-09 10:19
Oke, dankzij jullie hulp is het probleem nu opgelost, het bleek inderdaad een missende virtual te zijn. De uiteindelijke code is nu geworden:

C++:
1
2
3
4
5
public ref class MyFirstMenuItem : IRootMenuitem
{
        public:
        virtual int GetItem();      
};


en
C++:
1
2
3
4
int MyFirstMenuItem::GetItem()
{
    return 0;
}


Nu draait hij als een zonnetje :D

Iedereen bedankt voor het meedenken en het snelle posten natuurlijk. Btw ik had geen idee dat C++/CLR anders was dan C++ :o

[ Voor 14% gewijzigd door ThaStealth op 27-05-2008 17:09 ]

Mess with the best, die like the rest


Acties:
  • 0 Henk 'm!

  • roy-t
  • Registratie: Oktober 2004
  • Laatst online: 08-09 11:33
.oisyn schreef op dinsdag 27 mei 2008 @ 17:02:
[...]

Kun je in C# een method weer non-virtual maken (en dan bedoel ik niet sealen)?
...
Zonder te sealen zo te zien niet omdat je niet expliciet hoeft aan te geven dat de override ook virtual is. Ik zou zelf zo 1,2,3 geen manier weten zonder te sealen. (maargoed daar is seal natuurlijk oa voor)


EDIT: te sloom

[ Voor 60% gewijzigd door roy-t op 27-05-2008 17:14 ]

~ Mijn prog blog!


Acties:
  • 0 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 01:28

.oisyn

Moderator Devschuur®

Demotivational Speaker

C++/CLI is de naam. CLI staat voor Common Language Infrastructure en de R in CLR staat voor Runtime. De compiler maakt dus gebruik van CLI zodat de code onder de CLR kan runnen ;) . En om het ingewikkeld te maken is /CLR tevens de optie voor de VC++ compiler om de code als C++/CLI te interpreteren :P

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Acties:
  • 0 Henk 'm!

  • bigbeng
  • Registratie: Augustus 2000
  • Laatst online: 26-11-2021
.oisyn schreef op dinsdag 27 mei 2008 @ 17:02:
[...]
...
.edit: een method met dezelfde naam hoeft natuurlijk ook niet die base method te overriden. Dit kan immers ook:
C++:
1
2
3
4
5
6
7
8
9
10
11
12
13
public ref class MyFirstMenuItem : IRootMenuitem 
{ 
public:
    virtual int CompletelyDifferentName() = IRootMenuitem::GetItem
    { 
        return 0; 
    } 

    int GetItem() // nieuwe GetItem(), niet die uit IRootMenuitem
    {
        return 0;
    }
};
Sommige language constructies wil je gewoon niet mogelijk hebben :)
Ik begrijp wel dat het zinvol is als je meerdere interfaces implementeert met dezelfde methodenamen, maar jouw voorbeeld doet me gewoon de kriebels over mijn rug lopen :)
Ik neem aan dat je met een cast naar de interface wel weer gewoon de GetItem kunt aanroepen.

Acties:
  • 0 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 01:28

.oisyn

Moderator Devschuur®

Demotivational Speaker

Kan dat in C# niet? Ik zou het ook zeker niet aanraden, maar idd zoals je zegt soms met conflicterende interface methods is het handig. In C++ of Java implementeer je dan met een methods beide interfaces 8)7, zie dan maar eens waar de call vandaan kwam. Maar goed, wellicht moet je je design dan sowieso nog eens overpijnzen ;)

Anyway, ik trachtte te verklaren waarom de virtual misschien verplicht was :P

[ Voor 10% gewijzigd door .oisyn op 27-05-2008 17:31 ]

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Acties:
  • 0 Henk 'm!

  • Woy
  • Registratie: April 2000
  • Niet online

Woy

Moderator Devschuur®
.oisyn schreef op dinsdag 27 mei 2008 @ 17:29:
Kan dat in C# niet? Ik zou het ook zeker niet aanraden, maar idd zoals je zegt soms met conflicterende interface methods is het handig. In C++ of Java implementeer je dan met een methods beide interfaces 8)7, zie dan maar eens waar de call vandaan kwam. Maar goed, wellicht moet je je design dan sowieso nog eens overpijnzen ;)
Je kan in c# wel expliciet een interface implementeren, dus heb je geen probleem met conflicterende interface namen.
C#:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
public class MyClass : IInterface1, IInterface2
{
    void IInterface1.Foo()
    {
        Console.WriteLine("IInterface1.Foo");
    }

    void IInterface2.Foo()
    {
        Console.WriteLine("IInterface2.Foo");
    }
    
    public void Foo()
    {
        Console.WriteLine("MyClass.Foo");
    }
}

public interface IInterface1
{
    void Foo();
}

public interface IInterface2
{
    void Foo();
}

Al kan het natuurlijk wel voor verwarring zorgen en kun je het beter proberen te vermijden.
Anyway, ik trachtte te verklaren waarom de virtual misschien verplicht was
In c# hoeft een interface implementatie igg niet perse virtual te zijn. Ik kan ook niet echt een goede reden bedenken waarom dat wel zou moeten kunnen.
Kun je in C# een method weer non-virtual maken (en dan bedoel ik niet sealen)?
Hoe wou jij een method non-virtual maken zonder hem te sealen? Dat is toch exact wat sealen inhoud, hem weer non-virtual maken.

[ Voor 20% gewijzigd door Woy op 27-05-2008 20:03 ]

“Build a man a fire, and he'll be warm for a day. Set a man on fire, and he'll be warm for the rest of his life.”


Acties:
  • 0 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 01:28

.oisyn

Moderator Devschuur®

Demotivational Speaker

rwb schreef op dinsdag 27 mei 2008 @ 19:57:
Hoe wou jij een method non-virtual maken zonder hem te sealen? Dat is toch exact wat sealen inhoud, hem weer non-virtual maken.
Nou ja eigenlijk een stapje hoger op de ladder :). Als je 'm sealed betekent dat je 'm nog override, maar dat een derived class 'm niet verder mag overriden. Als je 'm non-virtual zou maken zou dat betekenen dat dat ook geen override is (hij is immers niet virtual). Volgens mij kan dat in C++/CLI ook wel:
C++:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
ref struct A
{
    virtual void Bla() { }
};

ref struct B : A
{
    virtual void Bla() { } // override
};

ref struct B : A

    void Bla() = new { } // override niet B.Bla(), B.Bla() is de "hoogste" A.Bla() implementatie.
};


(het keyword struct in C++/CLI niet verwarren met structs uit C# trouwens)

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Acties:
  • 0 Henk 'm!

  • Woy
  • Registratie: April 2000
  • Niet online

Woy

Moderator Devschuur®
.oisyn schreef op dinsdag 27 mei 2008 @ 20:44:
[...]

Nou ja eigenlijk een stapje hoger op de ladder :). Als je 'm sealed betekent dat je 'm nog override, maar dat een derived class 'm niet verder mag overriden. Als je 'm non-virtual zou maken zou dat betekenen dat dat ook geen override is (hij is immers niet virtual). Volgens mij kan dat in C++/CLI ook wel:
C++:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
ref struct A
{
    virtual void Bla() { }
};

ref struct B : A
{
    virtual void Bla() { } // override
};

ref struct B : A

    void Bla() = new { } // override niet B.Bla(), B.Bla() is de "hoogste" A.Bla() implementatie.
};
dat kan in C# ook gewoon
C#:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
public class A
{
    public virtual void Bla(){}
}

public class B : A
{
    public override void Bla(){} //override
}

public class C : B
{
    public new void Bla(){} //geen override maar hide B.Bla() wel
}
(het keyword struct in C++/CLI niet verwarren met structs uit C# trouwens)
Nee want dan gaat het verhaal zowiezo niet op omdat structs in C# per definitie sealed zijn ;)

“Build a man a fire, and he'll be warm for a day. Set a man on fire, and he'll be warm for the rest of his life.”

Pagina: 1