|
| Erklæring i header-fil Fra : Torben Frandsen |
Dato : 13-02-04 11:59 |
|
Hej gruppe
Jeg er ved at skrive en wrapper til et API, som er skrevet i C, så jeg kan
benytte det i .Net. Det giver anledning til en masse hyggelæsning i
dokumentationen og de medfølgende header-filer. Jeg har ikke skrevet noget i
C siden en gang for 12-14 år siden, så noget af den hukommelse jeg har brugt
på C-syntax er blevet reallokeret.
Jeg stødt på følgende erklæring (for det er vel en erklæring?):
extern M_APIG1 int M_APIG2 _mill_optind;
Hvordan skal den forstås? Jeg er naturligvis med på hvordan en normal
erklæring ser ud, men 'M_APIG1' og 'M_APIG2' passer ikke rigtig ind i mit
verdensbillede. De kommer i øvrigt til verden på følgende vis:
#if defined(BlaBlaBla)
#define M_APIG1 __declspec(dllexport)
#define M_APIG2
#elif (BlaBla)
#define M_APIG1 __declspec(dllimport)
#define M_APIG2
#else
#define M_APIG1
#define M_APIG2
#endif
Torben
| |
Troels Thomsen (17-02-2004)
| Kommentar Fra : Troels Thomsen |
Dato : 17-02-04 10:44 |
|
Jeg så godt din post for et par dage siden men regnede med at nogle experter
hurtigt ville sætte denne sag på plads. Er du kommet videre?
med forbehold:
__declspec(dllexport) og lignende afgør hvilke navne dine funktioner helt
præcist får internt når de bliver oversat. Normalt er det jo ligegyldigt
hvis du også bare kalder funktionerne fra koden, men hvis du nu vil bygge en
dll er det måske uønsket at din funktion
long myAdd(int a , int b)
får navnet
__!#¤"#¤__myAdd@8.
(idet du skal bruge dette navn fra de applikationer der bruger dll'en, med
mindre du får lavet en mapning mellem de mærkelige navne og noget mere
læseligt ....)
Hvis du skal lave noget der kan kaldes fra .NET skal du vel ikke bruge alt
dette, idet dll'er er afskaffet ? (hedder assemblies, eller ?)
mvh
Troels
"Torben Frandsen" <torben@rem.airsupport.dk> skrev i en meddelelse
news:402cae0f$0$27468$edfadb0f@dread16.news.tele.dk...
> Hej gruppe
>
> Jeg er ved at skrive en wrapper til et API, som er skrevet i C, så jeg kan
> benytte det i .Net. Det giver anledning til en masse hyggelæsning i
> dokumentationen og de medfølgende header-filer. Jeg har ikke skrevet noget
i
> C siden en gang for 12-14 år siden, så noget af den hukommelse jeg har
brugt
> på C-syntax er blevet reallokeret.
>
> Jeg stødt på følgende erklæring (for det er vel en erklæring?):
>
> extern M_APIG1 int M_APIG2 _mill_optind;
>
> Hvordan skal den forstås? Jeg er naturligvis med på hvordan en normal
> erklæring ser ud, men 'M_APIG1' og 'M_APIG2' passer ikke rigtig ind i mit
> verdensbillede. De kommer i øvrigt til verden på følgende vis:
>
> #if defined(BlaBlaBla)
> #define M_APIG1 __declspec(dllexport)
> #define M_APIG2
> #elif (BlaBla)
> #define M_APIG1 __declspec(dllimport)
> #define M_APIG2
> #else
> #define M_APIG1
> #define M_APIG2
> #endif
>
> Torben
>
>
| |
Torben Frandsen (17-02-2004)
| Kommentar Fra : Torben Frandsen |
Dato : 17-02-04 13:23 |
|
Troels Thomsen wrote:
> Jeg så godt din post for et par dage siden men regnede med at nogle
> experter hurtigt ville sætte denne sag på plads.
Åbenbart ikke. Om det så er fordi mit spørgsmål er for svært, for trivielt
eller for dårligt formuleret, står hen i det uvisse.
> Er du kommet videre?
Ja, men ikke med dette :)
> med forbehold:
> __declspec(dllexport) og lignende afgør hvilke navne dine funktioner
> helt præcist får internt når de bliver oversat.
Okay, det der egentlig forvirrede mig var at der ikke bare stod "[access
modifier] type navn;" men det handler vel bare om at finde en #define
sætning for at se hvad der menes med de andre ord?
> Normalt er det jo
> ligegyldigt hvis du også bare kalder funktionerne fra koden, men hvis
> du nu vil bygge en dll er det måske uønsket at din funktion
> long myAdd(int a , int b)
> får navnet
> __!#¤"#¤__myAdd@8.
> (idet du skal bruge dette navn fra de applikationer der bruger
> dll'en, med mindre du får lavet en mapning mellem de mærkelige navne
> og noget mere læseligt ....)
Det forstås.
> Hvis du skal lave noget der kan kaldes fra .NET skal du vel ikke
> bruge alt dette
Njaej ... Jeg skal lave nogle kald ud til en gammeldaws dll vha. P/Invoke.
Funktionernes navne gives naturligvis af dokumentationen i samarbejde med en
dependency walker, men for at marshalle data korrekt frem og tilbage må jeg
tage header-filerne i ed.
> idet dll'er er afskaffet ? (hedder assemblies, eller ?)
Nu hedder det godt nok assemblies, men de har stadig en .dll-extention. Det
ændrer sig åbenbart ikke - det gjorde det heller ikke da COM kom til verden.
Set fra et passende højt abstraktionsniveau er det jo også stadig det samme.
Dll-helvedet er derimod afskaffet. Og må det hvile i fred.
Torben
| |
Ivan Johansen (17-02-2004)
| Kommentar Fra : Ivan Johansen |
Dato : 17-02-04 18:48 |
|
Troels Thomsen wrote:
> med forbehold:
> __declspec(dllexport) og lignende afgør hvilke navne dine funktioner helt
> præcist får internt når de bliver oversat. Normalt er det jo ligegyldigt
> hvis du også bare kalder funktionerne fra koden, men hvis du nu vil bygge en
> dll er det måske uønsket at din funktion
> long myAdd(int a , int b)
> får navnet
> __!#¤"#¤__myAdd@8.
> (idet du skal bruge dette navn fra de applikationer der bruger dll'en, med
> mindre du får lavet en mapning mellem de mærkelige navne og noget mere
> læseligt ....)
Det er vist ikke helt rigtigt. det du beskriver her kaldes name mangling
og fjernes med extern "C".
__declspec(dllexport) angiver at en funktion eller variabel skal
eksporteres fra en DLL og erstatter dermed DEF-filer. Hvis en funktion
ikke er erklæret med __declspec(dllexport) kan den ikke kaldes fra det
program som vil bruge DLL'en. Ligeledes bruges __declspec(dllimport) til
at fortælle at en variabel eller funktion findes i en DLL og ikke lokalt.
Ivan Johansen
| |
Troels Thomsen (18-02-2004)
| Kommentar Fra : Troels Thomsen |
Dato : 18-02-04 09:08 |
|
>
> __declspec(dllexport) angiver at en funktion eller variabel skal
> eksporteres fra en DLL og erstatter dermed DEF-filer.
Ok, det var en sammenblanding
| |
Troels Thomsen (18-02-2004)
| Kommentar Fra : Troels Thomsen |
Dato : 18-02-04 09:24 |
|
> #if defined(BlaBlaBla)
> #define M_APIG1 __declspec(dllexport)
> #define M_APIG2
> #elif (BlaBla)
> #define M_APIG1 __declspec(dllimport)
> #define M_APIG2
> #else
> #define M_APIG1
> #define M_APIG2
> #endif
>
Fordelen er iøvrigt at man kan bruge den samme header når man:
* genererer dll'en (#define BlaBlaBla)
* laver programmet der skal bruge dll'en (#define BlaBla)
* bruger sourcen direkte i et program (definer ingenting)
(Altså man skal kun vedligeholde én fil i stedet for flere)
| |
Torben Frandsen (20-02-2004)
| Kommentar Fra : Torben Frandsen |
Dato : 20-02-04 10:02 |
|
Troels Thomsen wrote:
> Fordelen er iøvrigt at man kan bruge den samme header når man:
> * genererer dll'en (#define BlaBlaBla)
> * laver programmet der skal bruge dll'en (#define BlaBla)
> * bruger sourcen direkte i et program (definer ingenting)
>
> (Altså man skal kun vedligeholde én fil i stedet for flere)
Er du synsk? Det er svjks lige præcis det der sker i mine BlaBla'er.
Nu vi er så godt i gang, er der også disse to, som gør mig mere tyndhåret
end jeg er i forvejen:
M_CB1 void (* M_CB2 user_func)(struct infopkt *ip,struct infopkt_stream
*ips,char *arg);
M_CB1 int (* M_CB2 func)(MILL_LINE *lp, char *arg, int section);
M_CB* er under alle omstændigheder defineret som ingenting, så de er der jo
nok enten af historiske grunde eller af hensyn til fremtidig vedligehold.
Torben
| |
|
|