Entwickler-Ecke

Sonstiges (Delphi) - Probleme mit 32bit zu 64bit Konvertierung (Avisynth.dll)


gispos - Mo 20.11.17 19:14
Titel: Probleme mit 32bit zu 64bit Konvertierung (Avisynth.dll)

Delphi-Quelltext
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:
type
   MSVC_AVS_Value = Int64;

   AVS_Value = record
     vtype: WideChar;
     array_size: Smallint;
     case Char of
       'c': (vclip: Pointer);
       'b': (vboolean: LongBool);
       'i': (vinteger: Integer);
       'f': (vfloating_pt: Single);
       's': (vstring: PChar);
       'a': (varray: PAVS_Value_array);
   end;


   ext_avs_invoke: function(env: PAVS_ScriptEnvironment; name: PAnsiChar; args: MSVC_AVS_Value; arg_names: PPAnsiChar): MSVC_AVS_Value; stdcall;
   ext_avs_release_value: procedure(v: MSVC_AVS_Value); stdcall;

   function avs_invoke(env: PAVS_ScriptEnvironment; name: PAnsiChar; args: AVS_Value; arg_names: PPAnsiChar = nil): AVS_Value;
   begin
     Result := AVS_Value(ext_avs_invoke(env, name, MSVC_AVS_Value(args), arg_names))
   end;

   procedure avs_release_value(v: AVS_Value);
   begin
     ext_avs_release_value(MSVC_AVS_Value(v));
   end;


Hallo,
seit Tagen versuche ich die function und procedure auf 64bit umzustellen, bisher leider ohne Erfolg.
Unter 32bit gibt es keine Probleme aber bei 64bit erhalte ich entweder "ungültige Typenumwandlung" oder eine nicht lauffähige Compelierung.

Versucht habe ich (auch unter 32bit):

Delphi-Quelltext
1:
2:
  ext_avs_release_value(MSVC_AVS_Value(@v))  
  ext_avs_release_value(MSVC_AVS_Value(Pointer(v)^))

Ergebnis: keine Compiler Fehler aber ein nicht lauffähiges Programm
auch:

Delphi-Quelltext
1:
   Result := AVS_Value(Pointer(ext_avs_invoke(env, name, MSVC_AVS_Value(@args), arg_names))^)                    

ergibt eine nicht lauffähige Compelierung, Pointer^ und Addr @ sind schuld.

Ich bin mir auch nicht sicher ob "ext_avs_invoke" einen PInt64 Adresse zurückgibt, es handelt sich um die Avisynth.dll die ich gerne in der 64bit Version nutzen möchte.
Wie behandle ich unter 64bit eine Adresse auf einen Record der aus einer DLL kommt? wie wandle ich ein Int64 zu einem Record?
Danke!


Narses - Di 21.11.17 04:05

Moin!

Ich weiß nicht so genau was du da machst, aber ich weiß, dass man eine 32bit-DLL nicht in einer 64bit-Anwendung nutzen kann (jedenfalls nicht ohne erhebliche Verrenkungen). :nixweiss:

cu
Narses


jaenicke - Di 21.11.17 08:27

Was die reine Übersetzung angeht, sollte es am einfachsten ohne große Verrenkungen so gehen:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
function avs_invoke(env: PAVS_ScriptEnvironment; name: PAnsiChar; args: AVS_Value; arg_names: PPAnsiChar = nil): AVS_Value;
var
  MsvcArgs: MSVC_AVS_Value absolute args;
  AvsResult: Int64 absolute Result;
begin
  AvsResult := ext_avs_invoke(env, name, MsvcArgs, arg_names);
end;
Allerdings passt die Größe des Records so gar nicht, denn schon der Pointer in vclip ist ja dort 64 Bit groß. Der ganze Record passt also in die Größe eines Int64 gar nicht herein.

Deshalb frage ich mich wie user profile iconNarses, ob du wirklich eine 64-Bit DLL hast und dort die Schnittstelle wirklich so wie unter 32-Bit aussieht?


Delete - Di 21.11.17 10:08

- Nachträglich durch die Entwickler-Ecke gelöscht -


gispos - Di 21.11.17 18:42

user profile iconNarses hat folgendes geschrieben Zum zitierten Posting springen:
Moin!

Ich weiß nicht so genau was du da machst, aber ich weiß, dass man eine 32bit-DLL nicht in einer 64bit-Anwendung nutzen kann (jedenfalls nicht ohne erhebliche Verrenkungen). :nixweiss:

cu
Narses

user profile icongispos hat folgendes geschrieben Zum zitierten Posting springen:

...es handelt sich um die Avisynth.dll die ich gerne in der 64bit Version nutzen möchte.

Die 32bit Version verwende ich mit der 32bit Compelierung meines Programms. :D

user profile iconjaenicke hat folgendes geschrieben Zum zitierten Posting springen:

...und dort die Schnittstelle wirklich so wie unter 32-Bit aussieht?


An dass hatte ich nicht gedacht :oops: , Du wirst recht haben.
Ich konnte bisher keine Source der 64bit Version von Avisynth finden, genauer gesagt von der 64bit Avisynth+ Version die ich verwende.
(Nur zur Information, es gibt das normale Avisynth 32 + 64bit und eine Plus Version in 32 und 64bit, erkennbar am + )

Danke für die Antworten, ich werde weiter ver(suchen).
Gisbert


gispos - Mi 22.11.17 19:46

Hallo,
ich habe es geschafft, war eigentlich ganz einfach. :roll: :D
Kein MSVC_AVS_Value verwenden, den Int64 typ MSVC_AVS_Value aus allen DLL Aufrufen und Rückgabewerte durch AVS_Value ersetzen und direkt den Record übergeben.

Beispiele:

Delphi-Quelltext
1:
2:
  ext_avs_release_value: procedure(v: AVS_Value); stdcall;
  ext_avs_invoke: function(env: PAVS_ScriptEnvironment; name: PAnsiChar; args: AVS_Value; arg_names: PPAnsiChar): AVS_Value; stdcall;

Das typecasting wird nur für 32bit benötigt.

Ich habe auch die Source gefunden. Kleiner Auzug.

C++-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
// AVS_Value is layed out identicly to AVSValue
typedef struct AVS_Value AVS_Value;
struct AVS_Value {
  short type;  // 'a'rray, 'c'lip, 'b'ool, 'i'nt, 'f'loat, 's'tring, 'v'oid, or 'l'ong
               // for some function e'rror
  short array_size;
  union {
    void * clip; // do not use directly, use avs_take_clip
    char boolean;
    int integer;
    float floating_pt;
    const char * string;
    const AVS_Value * array;
  } d;
};

// AVS_Value should be initilized with avs_void.
// Should also set to avs_void after the value is released
// with avs_copy_value.  Consider it the equalvent of setting
// a pointer to NULL
static const AVS_Value avs_void = {'v'};


PS: Bei der 32 und 64bit gibt es doch keine Unterschiede bei der Schnittstelle.