Toon posts:

[C/C++] Probleem met scrrun.dll

Pagina: 1
Acties:

Verwijderd

Topicstarter
Goedemorgen :)

Ik heb een probleempje met het Dictionary object uit scrrun.dll
In VB gebruiken we dit ding, en dit werkt prima :+

Nu wil ik 'm dus gaan gebruiken in C/C++.
Appeltje eitje..dll importeren met:
code:
1
#import "scrrun.dll" no_implementation named_guids raw_interfaces_only rename_namespace("fso")

Tsjakkaa..nu kan ik in C/C++ dus m'n dictionary gebruiken :7

Voor het toevoegen van key/value paren aan de dictionary is de volgende functie:
code:
1
virtual HRESULT __stdcall Add ( VARIANT * Key, VARIANT * Item ) = 0;

Om deze functie goed te gebruiken moet ik er parameters van het type _variant_t in stoppen ipv VARIANT.

Zo dus:
code:
1
dict->Add( &_variant_t( "Blaat" ), &_variant_t( "schaap" ) );

Als ik VARIANT gebruik compileert het en draait het, maar wordt er niets aan de dictionary toegevoegd.

Nou is _variant_t een encapsulatie (ofzo) van VARIANT met een aantal toegevoegde functies/operatoren..maar toch vaag dat in de declaratie van de functies dan VARIANT types gebruikt worden.

Nu het volgende probleem...

Er is een functie om een ARRAY met alle aanwezige keys op te vragen. In VB is het return type van deze functie netjes een variant array.

In C/C++ echter is het een beetje vaag/fout :?

In de automagisch gegenereede header 'scrrun.tlh' wordt de functie als volgt gedeclareerd:
code:
1
virtual HRESULT __stdcall Keys ( VARIANT * pKeysArray ) = 0;

Stomme parameter is een pointer naar een variant...

Hoe gaat hier in vredesnaam een ARRAY van variants uit komen :?

Heb al vanalles geprobeerd..

- pointer naar een variant: VARIANT d
- pointer naar array varriantjes: VARIANT d[5]
- pointer naar een pointer naar een variant 8-)
- pointer naar een pointer naar een array van variantjes *D

Dezelfde dingen natuurlijk ook geprobeerd voor het _variant_t type.

En niets werkt...nou ja..het compileert en draait..maar zonder gewenst resultaat :'(

Is hier iemand die dit al een keer gefixt heeft?

Zit ik al fout bij het importeren van de dll, of moet ik een of andere brute constructie die parameter in schoppen?

Verwijderd

Ik kan niet zo een oplossing voor je bedenken, maar ik heb in de docs van Visual Studio wel een artikel gevonde over VARIANT. Het heet 'Article 4. The Ultimate Data Type'. Technical Articles -> Visual Tools -> Visual Basic -> Extending VB with C++ DLL's -> Art.4.

Verwijderd

overigens.... moet je niet LoadLibrary gebruiken om een dll te gebruiken? Zover ik weet gebruik je alleen import voor .libs.

Ik ging er aanvankelijk vanuit dat je wat problemen had met een datatype, maar als je geen resultaat hebt, zou het ook kunnen dat je geen functie aanroept die in die dll zit.

Verwijderd

Topicstarter
Bij het gebruik van #import werken (bijna) alle functies..

Zo kan ik wel:

- key/value paren toevoegen aan een dictionary
- values opvragen aan de hand van een key.
- aantal entries in dictionary opvragen

Ik gebruik de dictionary in een eigen DLL die weer door een VB applicatie gebruikt gaat worden.
Als parameter van een functie verwacht ik een Dictionary object.
code:
1
extern "C" __declspec( dllexport ) int __stdcall test( fso::IDictionary* dict )

Items die ik in VB in de dictionary plaats, kan ik er in C/C++ uithalen, en omgekeerd.

Verwijderd

heb je je variants wel zelf geinitaliseerd met VariantInit? das nodig namelijk

Verwijderd

Topicstarter
Yeps..alle variants zijn netjes geinitialiseerd..

Het gaat me vooral op het probleem met de Keys functie (zie boven).

Maakt niet uit wat ik probeer...alles dat uit die functie komt is drek..
Zijn geen fatsoenlijke variants van te bakken :(

Verwijderd

Op woensdag 09 januari 2002 10:23 schreef Pagan het volgende:
Voor het toevoegen van key/value paren aan de dictionary is de volgende functie:
code:
1
virtual HRESULT __stdcall Add ( VARIANT * Key, VARIANT * Item ) = 0;
Dit vind ik er een beetje merkwaardig uit zien. Hier zie ik een zuivere virtuele functie gedeclareerd, maar gebruik je die om functies aan te roepen in die dll??

Verwijderd

Topicstarter
Functie declaraties zijn inderdaad puur virtueel..

De header waar deze declaraties in staan wordt automatisch gegenereed als je #import gebruikt.

Verwijderd

Op woensdag 09 januari 2002 12:18 schreef Pagan het volgende:
Functie declaraties zijn inderdaad puur virtueel..

De header waar deze declaraties in staan wordt automatisch gegenereed als je #import gebruikt.
Ok, vandaar.

Heb je een voorbeeld van hoe je die functie Keys(..) aanroept? Misschien dat je eerst een VARIANT moet aanmaken, vervolgens intialiseren en daarna he adres ervan meegeeft aan Keys(..), maar ik weet dus niet hoe je dat soort dingen al doet...

Verwijderd

Topicstarter
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
extern "C" __declspec( dllexport ) int __stdcall test( fso::IDictionary* dict )
{
    HRESULT c;
    VARIANT v[2];

    // Variants moeten eerst geinitialiseerd worden :P
    for( int j = 0; j < 2; j++) { VariantInit( &v[j] ); }
    
    dict->Add( &_variant_t( "Blaat" ), &_variant_t( "schaap" ) );
    dict->Add( &_variant_t( "Boe" ), &_variant_t( "koe" ) );

    long i;
    dict->get_Count( &i );

//  dict->get_Item( &_variant_t( "Blaat" ), &v[0] );

    c = dict->Keys( v );

    return (int)i;
}

Tadaa.. :P

De functie aanroepen voor Add en get_Item werken.
get_Item werkt idd wel als er een normale VARIANT wordt meegegeven. ( was stiekum toch de initialisatie vergeten :Z)

Verwijderd

Topicstarter
In het bovenstaande stukje worden 2 key/value paren in de
dictionary gestopt.

De functie die het aantal opvraagt, geeft netjes 2 terug.

Nou verwacht ik (maar ja..wie ben ik ;() dat m'n array (v) netjes wordt gevuld met 2 variants.
Een voor "Blaat" en een voor "Boe".

Nadat de Keys functie is aangeroepen, is alleen v[0] veranderd in iets dat geen VARIANT meer is. Tenminste..geen geldige.

v[1] is en blijft echter VT_EMPTY

Verwijderd

En had je ook geprobeerd om dit te doen?
code:
1
2
3
4
5
c = dict->Keys( &v[0] );
//c evalueren

c = dict->Keys( &v[1] );
//c evalueren

Geen idee of dit werkt, in zo'n geval zou ik veel uitproberen (wat je al gedaan hebt). VARIANT is wel een uitgebreid type, dus nog genoeg mogelijkheden.

Verwijderd

Topicstarter
Hmmz..

Ik begin het vermoeden te krijgen dat ik een VARIANT terug krijg met daarin een SAFEARRAY..

Volgens mij zijn de enige veldjes die in die array kloppen, de velden die het aantal entries tellen :?

Weet iemand hoe ik zelf een safearray fabriek?

Verwijderd

Op woensdag 09 januari 2002 16:36 schreef Pagan het volgende:

Weet iemand hoe ik zelf een safearray fabriek?
Dat kun je vinden in de docs van Visual Studio. DIe kun je ook online vinden bij msdn.microsoft.com.
Iig heb ik een leuk verhaaltje kunnen vinden bij SAFEARRAY Data Type in die docs... ziet er zo uit:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
typedef struct FARSTRUCT tagSAFEARRAY {
    unsigned short cDims;      // Count of dimensions in this array.
    unsigned short fFeatures;    // Flags used by the SafeArray
                      // routines documented below.
#if defined(WIN32)
    unsigned long cbElements;    // Size of an element of the array.
                      // Does not include size of
                      // pointed-to data.
    unsigned long cLocks;     // Number of times the array has been 
                      // locked without corresponding unlock.
#else
    unsigned short cbElements;
    unsigned short cLocks;
    unsigned long handle;     // Unused but kept for compatibility.
#endif
    void HUGEP* pvData;          // Pointer to the data.
    SAFEARRAYBOUND rgsabound[1];      // One bound for each dimension.
} SAFEARRAY;

Verwijderd

Topicstarter
Yessss..ik heb 'm :)

Voor de mensen die het ook een keer nodig kunnen hebben:
code:
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
28
29
30
31
extern "C" __declspec( dllexport ) int __stdcall test( fso::IDictionary* dict )
{
      // Voeg 2 elementjes toe
    dict->Add( &_variant_t( "Blaat" ), &_variant_t( "schaap" ) );
    dict->Add( &_variant_t( "Boe" ), &_variant_t( "koe" ) );

      // Vraag het aantal elementjes in dictionaty op
    long size;
    dict->get_Count( &size );

    VARIANT keys;
    VariantInit( &keys );

    HRESULT result;

    SAFEARRAY* arr;

    // Resultaat is type 8204
    // is VT_ARRAY | VT_VARIANT
    result = dict->Keys( &keys );

    arr= keys.parray;

    VARIANT element;
    VariantInit( &element );

    long index = 0;
    result = SafeArrayGetElement( arr, &index, &element );

    return 0;
}

Het resultaat van de Keys functie is een VARIANT met daarin een SafeArray.

Hoop geklooi voordat ik daar achter kwam..nou ja..misschien te verwachten als je nooit met variants werkt enzo |:(
Pagina: 1