/ Forside / Teknologi / Udvikling / C/C++ / Nyhedsindlæg
Login
Glemt dit kodeord?
Brugernavn

Kodeord


Reklame
Top 10 brugere
C/C++
#NavnPoint
BertelBra.. 2425
pmbruun 695
Master_of.. 501
jdjespers.. 500
kyllekylle 500
Bech_bb 500
scootergr.. 300
gibson 300
molokyle 287
10  strarup 270
callback til c++ member function fra C lib~
Fra : Bear


Dato : 16-08-02 13:46

Hej there

Jeg benytter et C library (FMOD) til et lydprogram. Når FMOD skal fødes med
mere lyddata laver det et callback til en funktion som tager 4 parametre,
eksempelvis som følgende:

signed char streamcallback(FSOUND_STREAM *stream, void *buff, int len, int
param);

Mappingen mellem FMOD og callback funktionen bliver oprettet med følgende
funktion:
DLL_API FSOUND_STREAM * F_API FSOUND_Stream_Create(
FSOUND_STREAMCALLBACK callback,
int length,
unsigned int mode,
int samplerate,
int userdata
);

Problemet er at jeg vil have callback til at være en member funktion og ikke
en static funktion. Hvordan i alverden løser man det?

--
mvh

Bear
ICQ: 2745075



 
 
Bjarke Dahl Ebert (16-08-2002)
Kommentar
Fra : Bjarke Dahl Ebert


Dato : 16-08-02 15:54

"Bear" <bdr@NOSPAM.sol.dk> wrote in message news:ajis6s$aqg$1@sunsite.dk...

> signed char streamcallback(FSOUND_STREAM *stream, void *buff, int len, int
> param);
>
> Mappingen mellem FMOD og callback funktionen bliver oprettet med følgende
> funktion:
> DLL_API FSOUND_STREAM * F_API FSOUND_Stream_Create(
> FSOUND_STREAMCALLBACK callback,
> int length,
> unsigned int mode,
> int samplerate,
> int userdata
> );

Hvad er 'param' og hvad er 'userdata'?
Hvis du ikke kan plugge din callback function ind sammen med noget userdata,
så er det kun muligt at kalde en memberfunktion på et hardkodet (eller
rettere: globalt) objekt - for ellers er der jo simpelthen ikke nok "state"
tilstede i callback-kaldet.

Du bliver nødt til i første omgang at lave en "alm. C-funktion" (dvs. global
funktion eller statisk member funktion) som callback, og denne kan så kalde
videre til en member funktion. Det objekt der skal anvendes hertil kan du
enten lagre i en global variabel (hvis det er godt nok - det er jo ikke
sikkert at alle callbacks benytter samme objekt), eller på en eller anden
måde "plugge med ind", fx i 'userdata' med et cast. Men jeg ved som sagt
ikke om det er det userdata er til (dvs. om userdata kommer med tilbage i
callback'et som 'param', fx.). Det må fremgå af FMOD's dokumentation.


--------
Off topic, men jeg kan ikke lade være:
C og C++'s typesystem viser igen at de typer der håndteres, er for konkrete,
i stedet for at være det de burde være: TYPER, dvs. abstrakte interfaces.
Selvfølgelig bør myobj.mymeth have den type som mymeth er erklæret med. I
stedet er det en syntaksfejl. myobj.mymeth er ikke et udtryk i sig selv, men
fungerer kun i forbindelse med et kald. Det burde give en closure. Jeg kan
godt se hvorfor det er sådan i C++: typer definerer i virkeligheden et
storage-layout (i stedet for et *abstrakt* interface) og har en sizeof.
Abstraktion er normalt det vi gerne vil have, ikke memory-layout-definition.
Som programmør kan jeg imidlertid være ligeglad med *hvorfor* der er en
eller anden mangel - det der er interessant for mig, er at manglen er der. I
mere moderne sprog kan man sige:
FSOUND_Stream_Create(myobj.f, len, mode, samplerate, userdata)
bemærk myobj.f.
Hvis myobj.f(1,2,3) kan kaldes lokalt, hvorfor i alverden skal man så ikke
kunne udskyde dette kald ved at give myobj.f som foo-parameter til en
funktion der siger foo(1,2,3)? Det kan man heldigvis også i mere moderne
sprog.
--------

Mvh. Bjarke






Mogens Hansen (16-08-2002)
Kommentar
Fra : Mogens Hansen


Dato : 16-08-02 19:16


"Bjarke Dahl Ebert" <bebert@worldonline.dk> wrote in message
news:3d5d11ed$0$33511$edfadb0f@dspool01.news.tele.dk...


[8<8<8<]
> Det burde give en closure.

Det findes som en _overflødig_ sprogudvidelse i Borland C++Builder:
"__closure"
Så kan man skrive

void (__closure *derivedClosure)(int);
derivedClosure = derivedObject.new_func; // Get a pointer to the
'new_func' member.
// Note the closure is
associated with the
// particular object,
'derivedObject'.
derivedClosure(3); // Call 'new_func' through the closure.


[8<8<8<]
> Det kan man heldigvis også i mere moderne
> sprog.

Bare for god ordens skyld:
Det kan man også i C++.
Man kan lave en C++ funktion (á la streamcallback), som frit kan tage hvad
som helst, som kan kaldes med passende argumenter - uanset om det er globale
funktioner, member funktioner eller funktions objekter
Det er kendt viden hvordan man gør.
Måden falder helt i tråd med filosofien i C++: man skal ikke tilføje noget
til core-language som (stort set) kan laves lige så godt som et library. En
design-filosofi man kan være uenig i, men det betyder ikke at det ikke kan
lade sig gøre.

Det hjælper blot ikke Bear konkret, for som du rigtigt siger, har C-API'et
for lidt information til rådighed til at kunne kalde en member-funktion
direkte.

Venlig hilsen

Mogens Hansen



Bjarke Dahl Ebert (16-08-2002)
Kommentar
Fra : Bjarke Dahl Ebert


Dato : 16-08-02 22:16

"Mogens Hansen" <mogens_h@dk-online.dk> wrote in message
news:ajjfe2$q0j$1@news.cybercity.dk...

> [8<8<8<]
> > Det burde give en closure.
> Det findes som en _overflødig_ sprogudvidelse i Borland C++Builder:
> "__closure"

Jeg vidste næsten at det ville komme... Jeg kender godt denne
Borland-specialitet som de har udviklet udelukkende for at kunne lave
OnFisOgBallade event-handlere.
Man kan spekulere over hvorfor Borland har udvidet C++-sproget med denne
feature. Du siger at den er overflødig. Men hvad vil du ellers have at typen
af
&myobject.mymethod
skal være? (Den er jo void(__closure*)(int) i Borland - og en syntaksfejl i
C++).
Eller vil du hellere skrive
method_wrapper1<void, int>(myobject, &MyClass::mymethod)

Iøvrigt løser Borlands extension overhovedet ikke det evige problem med at
objektet kunne gå hen og dø før closuren dør.

> Så kan man skrive
>
> void (__closure *derivedClosure)(int);
> derivedClosure = derivedObject.new_func; // Get a pointer to the
> 'new_func' member.

Ja, det er også meget fint...
Men typen void(__closure *)(int) har desværre *intet som helst* med typen
void(*)(int) at gøre, og er dermed stort set ubrugelig. Den første *burde*
være en subtype af den anden, for den anden siger bare "pointer til noget
som kan kaldes med en int for at returnere void". En member kan kaldes på
den måde, men den kan bare ikke repræsenteres som en funktionspointer. Hvis
jeg holder en void(*)(int) så kunne jeg som programmør i princippet være
ligeglad med hvordan denne funktion er implementeret. En closure ville være
fin for mig, hvis det ikke lige var fordi alting skal være så fa'ens "exact
binary layout and static dispatch"-agtigt. Det er *kun* derfor man ikke
kan - der ville ikke være noget type-mæssigt galt som sådan.
Det samme kan man sige om en funktion
void g(int x , int y=10);
Den burde have en type som var en subtype af void(&)(int), for jeg kan jo se
med mine egne øjne at den kan kaldes med ét int-argument. Men nænej, vi må
endeligt ikke *holde* funktionen i en variabel der siger at den kan tage et
int-argument - kun kalde den som sådan en.

Hvorfor kan
g(42);
give mening, når
<sometype> g2=g;
g2(42);
ikke giver mening for nogen helst <sometype>. Mine indvolde fortæller mig at
der er noget galt.


Man kunne også blive lidt mere ivrig:
void h(double d);
Den kan jo også godt kaldes med en int, men kun ved at nævne h direkte, ikke
ved at lagre h i en variabel der siger at den er en funktion der kan tage en
int. Så h kan tage en int, men ikke rigtig alligevel...

> [8<8<8<]
> > Det kan man heldigvis også i mere moderne
> > sprog.
>
> Bare for god ordens skyld:
> Det kan man også i C++.

Nej, man kan *implementere* det i C++ - der er en stor forskel.

Hvis jeg vil erklære en funktion, foo, der tager en callback, vil du så
virkelig have at jeg skal skrive:

class Callback_int_void_abstract
{
public:
virtual void operator()(int) = 0;
};
// Wrapper of the above interface for ordinary C++ functions, since their
// C++ type is not what we want here
class Callback_int_void_ordinaryfunction
{
void(*f)(int);
public:
Callback_int_void_ordinaryfunction(void(*ff)(int)) : f(ff) { }
virtual void operator()(int x) { f(x); }
};
// Wrapper of the above interface for ordinary C++ member functions
template <class T>
class Callback_int_void_memberfunction
{
T& t;
void(T::*f)(int);
public:
Callback_int_void_memberfunction(T& tt, void(*ff)(int))
: t(tt), f(ff) { }
}
void foo(std::auto_ptr<Callback_int_void_abstract> cb); // takes ownership

// endelig kan jeg kalde foo således:
Callback_int_void_abstract* mycallback
= new Callback_int_void_memberfunction(myobject, &MyClass::mymethod);
foo(mycallback);

Hvor længe gider man det? Alt dette kan i andre sprog kan gøres som
foo(myobject.mymethod)

Der er utvivlsomt noget Boost-halløj der allerede har implementeret dele af
det ønskede. Men min pointe er at man ikke kan gøre det i sproget, man kan
implementere et "bedre sprog" ovenpå sproget - der er en stor forskel.
Desuden vil Boost, dig, mig, og alle mulige andre, have hver sin definition
af Callback_int_void_abstract, så det hele ender i et stort miskmask af
wrappere i stedet for at lade sprogets egne typer være direkte anvendelige
(uden at skulle wrappes).


I ML ville man sige noget i retning af:
foo :: (int -> unit) -> unit
slut, prut, finale. Den kan enhver dims af typen (int -> unit), uanset
hvordan dimsen har realiseret den type.

I Python kan man ikke erklære foo (derved slipper man også for en masse af
ovenstående pjat, fristes man til at sige . Men man kan _definere_ én af
slagsen så nemt som:
def foo(callback):
blabla
callback(42)
stored_callback = callback
osv...

def g(x, y=10): return x+y
foo(g) # virker
foo(myobj.mymethod) # virker også
foo("prut") # virker ikke. Jeg får en runtimefejl,
# der siger at "prut"(42) ikke giver mening.

> Man kan lave en C++ funktion (á la streamcallback), som frit kan tage hvad
> som helst, som kan kaldes med passende argumenter - uanset om det er
globale
> funktioner, member funktioner eller funktions objekter
> Det er kendt viden hvordan man gør.

Men det hjælper jo ikke mig, når jeg skal kalde denne function:
void foo(void(*callback)(int))
Jeg kan ikke bruge til noget at ham der skrev den funktion, *kunne* have
lavet den mere generisk. Hvis den ikke er det.

Jeg kan ikke forhindre andre i at skrive funktioner, som jeg skal kalde, på
denne måde. Jeg kan ikke tvinge dem til at bruge boost, eller hvad man nu
p.t. synes er fedt.
Problemet er, her som så mange andre steder, at C++'s typer er konkrete. Jeg
skal eksplicit skrive noget kode for at erklære abstrakte typer, som jeg så
må wrappe C++´s egne konkrete typer i.


Bjarke





Mogens Hansen (17-08-2002)
Kommentar
Fra : Mogens Hansen


Dato : 17-08-02 05:45


"Bjarke Dahl Ebert" <bebert@worldonline.dk> wrote in message
news:N4e79.4963$ww6.642929@news010.worldonline.dk...


[8<8<8< En masse kode 8<8<8<]
> Hvor længe gider man det? Alt dette kan i andre sprog kan gøres som

Dit bud er langt fra optimalt for C++
Det er kendt viden.

Venlig hilsen

Mogens Hansen




Anders J. Munch (17-08-2002)
Kommentar
Fra : Anders J. Munch


Dato : 17-08-02 12:42

"Mogens Hansen" <mogens_h@dk-online.dk> skrev:
>
> "Bjarke Dahl Ebert" <bebert@worldonline.dk> wrote:
>
>
> [8<8<8< En masse kode 8<8<8<]
> > Hvor længe gider man det? Alt dette kan i andre sprog kan gøres som
>
> Dit bud er langt fra optimalt for C++
> Det er kendt viden.

Det må du forklare nærmere.

- Anders




Mogens Hansen (17-08-2002)
Kommentar
Fra : Mogens Hansen


Dato : 17-08-02 14:58


"Anders J. Munch" <andersjm@inbound.dk> wrote in message
news:JEq79.5223$ww6.734879@news010.worldonline.dk...

> Det må du forklare nærmere.

Hvorfor [1] ? Der er vist ingen _pligt_ til at forklare.
Uden yderligere forklaring er det naturligvis Bjarke Dahl Eberts ord imod
mit - Bjarke Dahl Eberts troværdighed imod min. Men det generer mig
egentlig ikke.

Jeg gider simpelt hen ikke at tage de lange, ligegyldige diskutioner med
Bjarke Dahl Ebert.
Jeg nøjes med at pointere når hans udsagn er forkerte, vildledende eller
sub-optimale.
For at begrænse arbejdsmængden, må det nødvendigvis blive til korte
kommentarer.

Hvis folk søger oplysninger i dette forum for at blive klogere med hensyn
til C++, hjælper jeg gerne efter bedste evne.
Hvis folk blot vil føre sprog-krig, må det høre hjemme i en anden gruppe -
gerne en gruppe, der hedder noget med "advocacy".

Hvis folk ikke bryder sig om C++, så er det fint for mig - jeg har ikke
behov for at prøve at "omvende" nogen. Specielt ikke folk, der allerede er
omvendt til en anden "tro".
Men hvis der offentligt udgydes vildledning eller usandheder, baseret på ond
vilje, uvidenhed eller fordomme, syntes jeg det er ukonstruktivt, og det
fortjener _ingen_ obmærksomhed, udover en kort afvisning.

Jeg bryder mig da bestemt heller ikke lige meget om alle de sprog jeg
kender - men det gider jeg ikke bruge kræfter på at være sur over.

Jeg kan godt forstå frustrationen ved ikke at kunne lide C++ og så have et
arbejde hvor man skal bruge det hver dag.

Venlig hilsen

Mogens Hansen



[1]
Kig i bogen
Modern C++ Design
Andrei Alexandrescu
ISBN 0-201-70431-5
kapitel 5 "Generalized Functors", side 99-128
for et rimeligt godt bud.

Hans implementering af type-lister kan gøres bedre:
* uden brug af preprocessoren
* uden at skulle angive hvor mange argumenter der er
Hans udvalg af måder at kalde på kunne udvides lidt, så der også var
compile-time bundet funktioner, med deraf følgende muligheder for
væsentlige optimeringer i nogle situationer.
Jeg ville foretrække at tage en reference til et objekt i stedet for en
pointer, når man skal kalde en member-funktion.
Det er småting - vis mig eet design, som ikke kan kritiseres - specielt over
tid.

Andrei Alexandrescu's design klarer de fleste af de ting Bjarke Dahl Ebert
efterlyser i Borland's overflødige [2] "__closure" sprog-udvidelse, f.eks.:
* ligeværdig håndtering af globale funktioner og member-funktioner (og
alle kaldbare typer i C++):

<code>
void Function(int);

struct SomeFunctor
{
void operator()(int);
};

struct SomeClass
{
void MemberFunction(int);
};

void example()
{
typedef Functor<void, TYPELIST_l(int)> Func;
// Initialize with a function
Func cmd1(Function) ;

// Initialize with a functor
SomeFunctor fn;
Func cmd2(fn);

// Initialize with a pointer to object
// and a pointer to member function
SomeClass myObject;
Func cmd3(&my0bject,
&SomeC1ass::MemberFunction);

// Initialize a Functor with another
// (copying)
Func cmd4(cmd3);
}
</code>

Bemærk at Func er een type, og ikke flere typer fra et hieraki hvor man skal
vælge den rigtige afhængig af typen på det der skal kaldes. Derfor kan Func
objekter frit gives som argumenter til funktioner, der så kan lave callback
på hvad som helst.

* understøttelse af funktioner, hvori der indgår konvertering (f.eks. int
til double) af såvel argumenter som return-værdier

<code>
// Ignore arguments-not of interest
// in this example
const char* TestFunction(doub1e, double)
{
static const char buffer[] = "Hello, world!";
// It's safe to return a pointer to a static buffer
return buffer;
}

int main()
{
Functor<string, TYPELIST_2(int, int)> cmd(TestFunction);
// Should print "world!"
cout << cmd(10, 10).substr(7);
}
</code>

For mig er det udemærket at C++ tillader at skrive den slags biblioteker i
stedet for at have det indbygget.
For mig er det glimrende at forskellige domæne-eksperter kan skrive gode
biblioteker (f.eks. til matrice-beregning eller parsing) , som er nemme at
bruge for andre domæne-eksperter.

F.eks. kan man implementere en komplet parser til en simpel regnemaskine (á
la "2+3*-7+4") med følgende C++ kode:

<code - grammar definition>

rule<> expression, term, factor, integer;

integer = lexeme[ (!ch_p('-') >> +digit)[push_int()] ];
factor = integer
| '(' >> expression >> ')'
| ('-' >> factor)[do_negate()];
term = factor >>
*( ('*' >> factor)[make_op(multiplies<long>())]
| ('/' >> factor)[make_op(divides<long>())]
);
expression = term >>
*( ('+' >> term)[make_op(plus<long>())]
| ('-' >> term)[make_op(minus<long>())]
);

</code - grammar definition>

som er simpelt at læse for en der kender lidt til Extended Backus Normal
Form og lidt til C++. (Der er naturligvis klippet lidt simpel støtte-kode
væk).

Alternativet til at kunne lave sådanne gode biblioteker er f.eks.:
* at vente på sprog-designere, som hverken har tid eller ekspertise, skal
komme med samtlige nødvendige løsninger i tilstrækkelig kvalitet
* at bruge et sprog der er optimeret til domænet (f.eks. MatLab til
matrice-beregninger, lex/yacc til parsing, Excel til budget-simulering). Det
er udemærket, hvis
ens applikation ikke bevæger sig for langt uden for domænet.

[2]
"_closure" er overflødig, bortset fra eet meget væsentligt punkt for VCL:
binær kompatibilitet med Borland Delphi



Bjarke Dahl Ebert (17-08-2002)
Kommentar
Fra : Bjarke Dahl Ebert


Dato : 17-08-02 20:14

"Mogens Hansen" <mogens_h@dk-online.dk> wrote in message
news:ajlknq$6s5$1@news.cybercity.dk...

> // Initialize a Functor with another
> // (copying)
> Func cmd4(cmd3);
> }
> </code>

Du skriver at Func er én type der kan wrappe hvad som helst (kaldbart). Du
sprang dog lidt let hen over funktioner med default-argumenter (og flere
andre kaldbare ting, som ikke kan wrappes på den måde).

Mvh. Bjarke





Mogens Hansen (17-08-2002)
Kommentar
Fra : Mogens Hansen


Dato : 17-08-02 23:01


"Bjarke Dahl Ebert" <bebert@worldonline.dk> wrote in message
news:9oy79.6015$ww6.805406@news010.worldonline.dk...

> Du skriver at Func er én type der kan wrappe hvad som helst (kaldbart). Du
> sprang dog lidt let hen over funktioner med default-argumenter (og flere
> andre kaldbare ting, som ikke kan wrappes på den måde).

Jeg kan rimeligtvis ikke forklare hvad en bog bruger knap 30 sider på,
fyldestgørende på en nyhedsgruppe.
Der er direkte understøttelse for:
* globale funktioner
* pointer til globale funktioner
* referencer til funktioner
* objekter med operator() defineret
* resultatet af operator.* eller operator->* med en pointer til
member-funktion på højre side af udtrykket.

Funktioner med default argumenter kan også tilgåes via klassen - den er åben
for udvidelser. Alternativt kan man binde enkelt-parametre til en fast
værdi.

Venlig hilsen

Mogens Hansen



Bjarke Dahl Ebert (18-08-2002)
Kommentar
Fra : Bjarke Dahl Ebert


Dato : 18-08-02 08:54

"Mogens Hansen" <mogens_h@dk-online.dk> wrote in message
news:ajnb4q$20e0$1@news.cybercity.dk...

> Jeg kan rimeligtvis ikke forklare hvad en bog bruger knap 30 sider på,
> fyldestgørende på en nyhedsgruppe.

At en bog skal bruge 30 sider på det, understøtter vel blot min pointe.

Iøvrigt nægter jeg at tro at default-argumenter (og flere andre ting) kan
håndteres fornuftigt.
Men det bliver vi nok ikke enige om.


Mvh. Bjarke





Mogens Hansen (18-08-2002)
Kommentar
Fra : Mogens Hansen


Dato : 18-08-02 19:26


"Bjarke Dahl Ebert" <bebert@worldonline.dk> wrote in message
news:BpI79.6122$ww6.862815@news010.worldonline.dk...
> "Mogens Hansen" <mogens_h@dk-online.dk> wrote in message
> news:ajnb4q$20e0$1@news.cybercity.dk...
>
> > Jeg kan rimeligtvis ikke forklare hvad en bog bruger knap 30 sider på,
> > fyldestgørende på en nyhedsgruppe.
>
> At en bog skal bruge 30 sider på det, understøtter vel blot min pointe.

Nej, det understøtter ikke din pointe.

Du falder tilbage i en stil som jeg syntes vi har set før, hvor du drager
forhastede konklusioner uden at have det fornødne grundlag.
Kender du bogen og de 30 sider ?
Hvis du gør havde du formodentlig ikke kommet med dit design-forslag til
C++ callback her i tråden.

Bogen bruger det meste af de 30 sider på at forklare designet af
"Generalized Functors".
Som det ofte er tilfældet tjener det 2 formål:
* det helt konkrete at forklare designet
* det mere abstrakte at vise design teknikker som er nyttige i andre
sammenhænge
De 30 sider er umagen værd, og de bliver ikke brugt på hvordan man _bruger_
funktionaliteten.

Det er den her slags ligegyldig diskution som jeg egentlig ikke gider at
bruge krudt på.
Derfor mine tidligere korte kommentar til dine udsagn:
"Det kan man også i C++."
og
"Dit bud er langt fra optimalt i C++.
Det er kendt viden"
De eksempler jeg har postet på opfordring fra Anders J. Munch, viser at jeg
havde ret i mine udsagn.

Dermed har jeg ikke sagt at er løsningen i enhver henseende er perfekt eller
at der ikke findes interessante løsninger i andre sprog.
Jeg syntes blot at de indtryk af C++, som du i dine posting i denne tråd
fremfører, langtfra giver et retvisende billede af tingenes faktiske
tilstand. Den form for misinformation, der fremstår som om det er baseret på
faktuel viden, syntes jeg at vi har set foruroligende meget af fra din side
på det sidste.
Det bunder formodentlig i at du syntes at C++ er noget bras - men det _er_
trættende at høre på, specielt når det er baseret på din egen uvidenhed.

> Iøvrigt nægter jeg at tro at default-argumenter (og flere andre ting) kan
> håndteres fornuftigt.

Det er du velkommen til at nægte at tro på.
Vi skulle jo nødigt forstyrre dine fordomme på en solrig søndag.
Fortsat god week-end.


Venlig hilsen

Mogens Hansen











Anders J. Munch (17-08-2002)
Kommentar
Fra : Anders J. Munch


Dato : 17-08-02 18:31

"Mogens Hansen" <mogens_h@dk-online.dk> skrev:
> "Anders J. Munch" <andersjm@inbound.dk> wrote:
>
> > Det må du forklare nærmere.
>
> Hvorfor [1] ? Der er vist ingen _pligt_ til at forklare.

Bjarke viste et design.
Du kommenterede at det var kendt viden, at det kunne gøres meget bedre.
Jeg havde ingen anelse om, hvad du hentydede til.
Jeg så en mulighed for at lære noget.
Jeg stillede et opklarende spørgsmål.
Behøver du bide hovedet af mig for det?

> Uden yderligere forklaring er det naturligvis Bjarke Dahl Eberts ord imod
> mit - Bjarke Dahl Eberts troværdighed imod min. Men det generer mig
> egentlig ikke.

Bjarke benytter enhver lejlighed til sprog-advocacy, og det er irriterende.
Tro mig, det er endnu mere irriterende når man er enig i de synspunkter han
advokerer for :-/.

Hans troværdighed og tekniske niveau er der derimod ikke noget galt med. Det
kan du ikke bruge som argumentation.

> [1]
> Kig i bogen
> Modern C++ Design
> Andrei Alexandrescu
> ISBN 0-201-70431-5
> kapitel 5 "Generalized Functors", side 99-128
> for et rimeligt godt bud.

Tak

Jeg skal nok lade være med at kommentere det, så jeg ikke mod din vilje
trækker dig ind i en ligegyldig diskussion.

mvh. Anders




Mogens Hansen (17-08-2002)
Kommentar
Fra : Mogens Hansen


Dato : 17-08-02 19:08


"Anders J. Munch" <andersjm@inbound.dk> wrote in message
news:0Mv79.5966$ww6.781143@news010.worldonline.dk...
> "Mogens Hansen" <mogens_h@dk-online.dk> skrev:

> Jeg så en mulighed for at lære noget.
> Jeg stillede et opklarende spørgsmål.
> Behøver du bide hovedet af mig for det?

Nej, undskyld.
Jeg vil da gerne give informationen videre hvis jeg forventer at det bliver
modtaget i en positiv ånd.
Hvis jeg tror at det blot vil blive brugt til ligegyldig, destruktiv
argumentation, så ønsker jeg ikke at bidrage.

[8<8<8<]
> Hans troværdighed og tekniske niveau er der derimod ikke noget galt med.
Det
> kan du ikke bruge som argumentation.

Jeg mindes mere end eet eksempel på at han ikke har haft belæg for sine
udtalelser, og hvor han med stor skåsikkerhed har taget _fuldstændig_ fejl.
Men generelt syntes jeg da at Bjarke Dahl Eberts udtalelser bærer præg en en
stor viden -
især på "dk.edb.programmering"


Venlig hilsen

Mogens Hansen



Mogens Hansen (16-08-2002)
Kommentar
Fra : Mogens Hansen


Dato : 16-08-02 18:00


"Bear" <bdr@NOSPAM.sol.dk> wrote in message news:ajis6s$aqg$1@sunsite.dk...

> Problemet er at jeg vil have callback til at være en member funktion og
ikke
> en static funktion. Hvordan i alverden løser man det?

Du kan ikke få kaldt en member-funktion direkte.
Du er nødt til at have en global eller static member-funktion som er
callback funktionen, som så på en eller anden måde har adgang til en pointer
til det objekt, som skal have kaldt sin member-funktioner.

Somme tider kan man til et C-API give en void* til user-data med. Det kan så
være objekt-pegeren.
Somme tider kan man gemme objekt-pegeren i en global variabel (helst i
unnamed namespace), som call-back funktionen kan tilgå.

Hvis man har mange forskellige objekter, og ikke har noget godt sted at
gennem en eller anden form for objekt-identifikation (pointer, index ind i
et array etc.), kan man have behov for at mappen een callback funktion til
eet objekt.
Det kan man enten gøre ved at have mange faste callback funktioner med
tilhørende globale pointere, eller oprette dem dynamisk (ikke portabelt) på
run-time, hvis platformen tillader det.

Venlig hilsen

Mogens Hansen




Bear (16-08-2002)
Kommentar
Fra : Bear


Dato : 16-08-02 19:10

Mange tak for de uddybende svar

--
mvh

Bear
ICQ: 2745075
"Bear" <bdr@NOSPAM.sol.dk> wrote in message news:ajis6s$aqg$1@sunsite.dk...
> Hej there
>
> Jeg benytter et C library (FMOD) til et lydprogram. Når FMOD skal fødes
med
> mere lyddata laver det et callback til en funktion som tager 4 parametre,
> eksempelvis som følgende:
>
> signed char streamcallback(FSOUND_STREAM *stream, void *buff, int len, int
> param);
>
> Mappingen mellem FMOD og callback funktionen bliver oprettet med følgende
> funktion:
> DLL_API FSOUND_STREAM * F_API FSOUND_Stream_Create(
> FSOUND_STREAMCALLBACK callback,
> int length,
> unsigned int mode,
> int samplerate,
> int userdata
> );
>
> Problemet er at jeg vil have callback til at være en member funktion og
ikke
> en static funktion. Hvordan i alverden løser man det?
>
> --
> mvh
>
> Bear
> ICQ: 2745075
>
>



Søg
Reklame
Statistik
Spørgsmål : 177558
Tips : 31968
Nyheder : 719565
Indlæg : 6408925
Brugere : 218888

Månedens bedste
Årets bedste
Sidste års bedste