Gå til innhold

C#: Circular Dependency problem - elller høna og egget om du vil ;-)


Anbefalte innlegg

Folkens. Følgende problemstilling:

Jeg har et program skrevet i Clarion. Dette programmet kan bruke Windows API.

 

Så har jeg et web service bibliotek skrevet i C#

 

For å få Clarion programmet til å kalle metoder i C# prosjektet så har jeg laget en C++ wrapper.

 

Måten jeg snakker med C++ wrapperen på fra Clarion er i gjennom et c++ Interface. Clarion kan nemlig referere direkte til C++ interfaces.

 

Dette er bra, og virker som bare det.

 

Og C++ kan kalle Clarion sine Interfaces direkte på samme måte. Har med andre ord en toveis komunikasjone mellom C++ og Clarion.

 

Så kommer problemstillingen. Jeg vil kalle Clarion funksjoner fra C# siden. Jeg vil gjerne bruke C++ wrapperen til dette fordi den allerede har satt opp en tilknytning mellom Clarion programmet og C# biblioteket, men når jeg prøver å adde C++ prosjektet til C# prosjektet så får jeg Circular Dependies meldinger, som er forståelig.

 

Min første tanke var å mekke et nytt C# library prosjekt, som skulle referere til C++ biblioteket, men Visual Studio er litt for smart. Den stopper meg når jeg prøver å legge dette prosjektet inn i referanse lista til C# programmet. Klarte ikke lure Visual Studio her.

 

Løsningsforslag er usansynlig velkomne her og jeg takker selvsagt på forhånd til alle dere som bidrar til at unge heien får en lykkelig hverdag... lol

Endret av HDSoftware
Lenke til kommentar
Videoannonse
Annonse

Folkens. Følgende problemstilling:

Jeg har et program skrevet i Clarion. Dette programmet kan bruke Windows API.

 

Så har jeg et web service bibliotek skrevet i C#

 

For å få Clarion programmet til å kalle metoder i C# prosjektet så har jeg laget en C++ wrapper.

 

Måten jeg snakker med C++ wrapperen på fra Clarion er i gjennom et c++ Interface. Clarion kan nemlig referere direkte til C++ interfaces.

 

Dette er bra, og virker som bare det.

 

Og C++ kan kalle Clarion sine Interfaces direkte på samme måte. Har med andre ord en toveis komunikasjone mellom C++ og Clarion.

 

Så kommer problemstillingen. Jeg vil kalle Clarion funksjoner fra C# siden. Jeg vil gjerne bruke C++ wrapperen til dette fordi den allerede har satt opp en tilknytning mellom Clarion programmet og C# biblioteket, men når jeg prøver å adde C++ prosjektet til C# prosjektet så får jeg Circular Dependies meldinger, som er forståelig.

 

Min første tanke var å mekke et nytt C# library prosjekt, som skulle referere til C++ biblioteket, men Visual Studio er litt for smart. Den stopper meg når jeg prøver å legge dette prosjektet inn i referanse lista til C# programmet. Klarte ikke lure Visual Studio her.

 

Løsningsforslag er usansynlig velkomne her og jeg takker selvsagt på forhånd til alle dere som bidrar til at unge heien får en lykkelig hverdag... lol

 

Vet ikke om du har mulighet til å implementere f.eks. C++ interfacene i Clarion. Men da kunne du jo laget en Dll med alle interfacer som skal brukes over "grensesnittet" mellom Clarion og C++. Og for den del også mellom C++ og C#. Du kan så lage en factory eller det jeg kaller en "ApplicationContext" som syr sammen selve programmet. Og hvem som skal kommunisere med hva. Med andre ord er alle dllene selvstendige utenom en felles dll i bunn. På toppen har du en hoved dll som syr sammen programmet.

 

I mitt tilfelle har jeg en felles dll med interfacer som skal implementeres av objeketer som skal være tegnbare, søkbare etc.

Jeg har 5-6 dller på toppen. Som er uavhengige av hverandre. Mens .exe filen på toppen legger til tegnbare objekter fra de forskjellige dllene i en Drawable liste siden de alle implementerer interfacet fra felles dllen.

 

Vet ikke om dette hjelper deg men...

Lenke til kommentar

Som jeg skriver :

Måten jeg snakker med C++ wrapperen på fra Clarion er i gjennom et c++ Interface. Clarion kan nemlig referere direkte til C++ interfaces.

Dette er bra, og virker som bare det.

Og C++ kan kalle Clarion sine Interfaces direkte på samme måte. Har med andre ord en toveis komunikasjone mellom C++ og Clarion.

Altså er ikke problemet mitt mellom C++ og Clarion

 

La meg forenkle det enda mer.

Glem Clarion i hele dette.

 

Prosjekt 1, som genererer EXE fil er i C++

Prosjekt 2, som genererer .NET kode er i C#

 

Prosjekt 1 bruker Prosjekt 2 sie funksjoner

Prosjekt 1 inneholder funksjoner som prosjekt 2 skal nå

 

Hvordan ville du løst dette?

Lenke til kommentar

Som jeg skriver :

Måten jeg snakker med C++ wrapperen på fra Clarion er i gjennom et c++ Interface. Clarion kan nemlig referere direkte til C++ interfaces.

Dette er bra, og virker som bare det.

Og C++ kan kalle Clarion sine Interfaces direkte på samme måte. Har med andre ord en toveis komunikasjone mellom C++ og Clarion.

Altså er ikke problemet mitt mellom C++ og Clarion

 

La meg forenkle det enda mer.

Glem Clarion i hele dette.

 

Prosjekt 1, som genererer EXE fil er i C++

Prosjekt 2, som genererer .NET kode er i C#

 

Prosjekt 1 bruker Prosjekt 2 sie funksjoner

Prosjekt 1 inneholder funksjoner som prosjekt 2 skal nå

 

Hvordan ville du løst dette?

 

1: Legg alle interfacer for både prosjekt 1 og 2 i en felles dll (Prosjekt3)

2: Implementer interfacer fra Prosjekt3 i prosjekt 1 og 2.

3. Prosjekt 1 setter opp objektene i prosjekt 2 via dependency injection med interfacer definert i prosjekt 3. Det betyr at prosjekt 2 ikke refererer prosjekt 1 men den bruker koden gjennom interfacene som er definert i Prosjekt3.

4: Ideelt sett ville jeg satt opp Prosjekt 1(exe) som en dll og hatt en dll på toppen som knytter sammen objektene med DI.

 

Med en slik løsning får du 4 assemblyer

 

1, Exe

2. Dll logikk

3. Dll logikk

4. Dll felles interfacer for at 2 skal kunne kalle 3 og motsatt.

 

1. Refererer 2,3 og 4

2, Refererer 4

3. Refererer 4

4. Refererer ingen

 

Mao. Ingen sirkulær logikk.

 

En alternativ "grisemåte" å gjøre det på er å koble 1 til 2 med hard kobling og 2 kan laste objekter fra 1 via System.Reflection og kaste disse til interfacer definert i Prosjekt 2. Med en slik løsning slipper du å definere ekstra dller som jeg forslår over.

Lenke til kommentar

Glimrende. Takker...

 

Men så kommer spørsmålet om interfaces og C++/C#

Hvordan kan jeg benytte et C++ Interface i C#?

 

For å trekke inn Clarioin igjen så er jo måten jeg gjør det på slik:

 

i Clarion:

CWrapperInterface &= Api_CDLL_GetInterface(Self.CallbackInterface)

 

der Self.CallbackInterface er et interface definert i Clarion som C++ kan lese og c++ returnerer sitt eget interface som jeg lagrer i CWrapperInterface.

 

Skulle derfor gjerne kunen gjort noe av det samme med C#. Det vil si at C++ DLL'en må kunne gjøre noe slik:

 

ThisNetWrapper = NETManager::GetInterface(ThisCInterface);

 

og i C# koden ønsker jeg noe slikt:

 

public iNetWrapper GetInterface(iCInterfaceType pCInterface)

{

this.cWrapper = pCInterface;

return this.NetWrapperInterface;

}

 

Lar det seg gjøre?

Jeg gjetter jo på at det må la seg gjøre siden du sier at komunikasjonen skal gå via et interface, noe jeg jo allerede gjør mellom C++ og Clarion.

 

takker for inspill

Lenke til kommentar

Glimrende. Takker...

 

Men så kommer spørsmålet om interfaces og C++/C#

Hvordan kan jeg benytte et C++ Interface i C#?

 

For å trekke inn Clarioin igjen så er jo måten jeg gjør det på slik:

 

i Clarion:

CWrapperInterface &= Api_CDLL_GetInterface(Self.CallbackInterface)

 

der Self.CallbackInterface er et interface definert i Clarion som C++ kan lese og c++ returnerer sitt eget interface som jeg lagrer i CWrapperInterface.

 

Skulle derfor gjerne kunen gjort noe av det samme med C#. Det vil si at C++ DLL'en må kunne gjøre noe slik:

 

ThisNetWrapper = NETManager::GetInterface(ThisCInterface);

 

og i C# koden ønsker jeg noe slikt:

 

public iNetWrapper GetInterface(iCInterfaceType pCInterface)

{

this.cWrapper = pCInterface;

return this.NetWrapperInterface;

}

 

Lar det seg gjøre?

Jeg gjetter jo på at det må la seg gjøre siden du sier at komunikasjonen skal gå via et interface, noe jeg jo allerede gjør mellom C++ og Clarion.

 

takker for inspill

 

Hei. Fant en løsning for deg på denne siden:

http://www.switchonthecode.com/tutorials/implementing-csharp-interfaces-in-cplusplus


public interface MyInterface
{
 float InterfacePropertyOne { get; set; }

 int InterfaceMethodOne();

 string InterfaceMethodTwo();
}

Implementing properties in managed C++ is fairly similar to C#. Here's the new C++ implementation of the interface.

public ref class Class1 : public CSharpLib::MyInterface
{
public:
 virtual int InterfaceMethodOne() { return 0; };

 virtual System::String^ InterfaceMethodTwo() {return ""; };

 virtual property float InterfacePropertyOne
 {
   void set(float value) { };
   float get() { return 0; };
 };
};

Her implementeres imidlertid et C# interface i C++. Men det burde ikke være noe problem å gå ander veien heller. Uansett løser jo dette problemet ditt om du definerer alle interfacene i C# :)

 

Men så lenge du legger til CLR støtte i C++ dllen din så burde det ikke være noe problem å gå begge veier.

 

Håper dette hjelper

Endret av OleM80
Lenke til kommentar

Du traff spikeren rett på knåtten! Genialt enkelt og neste en selvfølge. Det er akkurat dette jeg var ute etter!!

 

Dermed har jeg full komunikasjon mellom mitt Clarion program og C#. Så forresten at du hadde en tilsvarende tråd tidligere. Regner med at du bruker denne teknikken der også, eller noe tillsvarende...

Lenke til kommentar

Du traff spikeren rett på knåtten! Genialt enkelt og neste en selvfølge. Det er akkurat dette jeg var ute etter!!

 

Dermed har jeg full komunikasjon mellom mitt Clarion program og C#. Så forresten at du hadde en tilsvarende tråd tidligere. Regner med at du bruker denne teknikken der også, eller noe tillsvarende...

 

Så bra :new_woot:

 

Litt mer grisete det jeg måtte gjøre. :whistle:

Jeg har et VB 6.0 program som skal bruke en native C++ dll via C#.

VB 6.0 kan bare laste C# dller som ligger i GAC og som en kjører REGASM på. Mens native C++ dllen ikke er mulig å registere i GAC. Og den kan heller ikke brukes direkte fra C#.

 

Løsningen ble som følger(Følg godt med nå :p )

1. VB 6.0(1) Kobler seg direkte via en hard kobling til C# dll(2) i GAC

2. C# dll(2) i GAC inneholder endel generelle interfacer. Disse brukes av en C++ CRL wrapper som ligger på en mappe som VB 6.0 setter opp i dll 2 :)

3. C#dllen (2) vet hvor C++ wrapperen(3) ligger og loader denne via System.Reflection og caster den til et kjent interface i sin egen dll (også nevnt som en mulig løsning til deg tidligere)

4. C++ wrapperen(3) kontakter C++ native API et som ligger på samme mappe.

 

Koblingene mine ble som følger:

1. Refererer 2

2. Refererer ingen (men den laster 3 via reflection og caster den til et lokalt interface)

3. Refererer 2 og 4

4. Refererer ingen

 

Løsningen involverer VB6.0-C#-C++ CLR-C++ ABI :thumbup:

 

Med andre ord en liten utfordring for en som ikke kan C++ :D

 

Supert at det ordnet seg for deg!

Endret av OleM80
Lenke til kommentar

Opprett en konto eller logg inn for å kommentere

Du må være et medlem for å kunne skrive en kommentar

Opprett konto

Det er enkelt å melde seg inn for å starte en ny konto!

Start en konto

Logg inn

Har du allerede en konto? Logg inn her.

Logg inn nå
  • Hvem er aktive   0 medlemmer

    • Ingen innloggede medlemmer aktive
×
×
  • Opprett ny...