Neues Thema starten

Aufruf von worm_tse_listRegisteredClients in C#

Hi,

wir scheitern derzeit daran die registrierten Clients auszulesen.


Der Client-Struct sieht wie folgt aus:

 

[StructLayout(LayoutKind.Sequential)]
public struct Clients
{
     public int amount;
     [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16 * 31)]
     public char[] clientIds;
}

 

 

und der DLL-Import so: 

[DllImport("WormAPI.dll", CallingConvention = CallingConvention.Cdecl)]
private static extern int worm_tse_listRegisteredClients(IntPtr info, int toSkip, out Clients clients);

 

Der Aufruf so:

Clients clients = new Clients();
int err = worm_tse_listRegisteredClients(info, toSkip, out clients);

 

Als Fehlermeldung erhalten wir immer Code 3 - WORM_ERROR_IO

clients ist mit 496 x \0 befüllt, aber anscheinend kann die TSE nicht in den Speicher schreiben.


Wir haben es auch mit einem IntPtr versucht:

IntPtr pointer = Marshal.AllocHGlobal(Marshal.SizeOf(clients));
Marshal.StructureToPtr(clients, pointer, false);
int err = worm_tse_listRegisteredClients(info, toSkip, out pointer);


selber Fehler.


Hat jemand die Methode schon erfolgreich eingebaut?



Mit freundlichen Grüßen,

Christian Weiterer


Ich habe 

Snippet

List<stringclientList = new List<string>();
 var err = (ErrorCodesworm_tse_listRegisteredClients(_swissbitContext, 0, out var clients);
 
 for (int i = 0; i < clients.amount; i++) {
 clientList.Add(new string(clients.clientIds.Skip(i * 31).Take(31).ToArray())?.Trim('\0'));
 }
 
 return clientList;



Snippet
[DllImport("WormAPI.dll", CallingConvention = CallingConvention.Cdecl)]
private static extern int worm_tse_listRegisteredClients(IntPtr infoint toSkipout Clients clients);

Snippet

public IList<stringGetRegisteredClients()
{
 List<stringclientList = new List<string>();
 var err = (ErrorCodesworm_tse_listRegisteredClients(_swissbitContext, 0, out var clients);
 
 for (int i = 0; i < clients.amount; i++) {
 clientList.Add(new string(clients.clientIds.Skip(i * 31).Take(31).ToArray())?.Trim('\0'));
 }
 
 return clientList;
}


Snippet
[DllImport("WormAPI.dll", CallingConvention = CallingConvention.Cdecl)]
private static extern int worm_tse_listRegisteredClients(IntPtr infoint toSkipout Clients clients);

Hallo,

läuft die Methode aus deinem Snippet denn erfolgreich ohne Fehler durch?

Wir bekommen leider immer noch den selben Fehler, auch wenn wir 1 zu 1 den entsprechenden Code von dieser Seite kopieren: https://support.gastro-mis.de/support/solutions/articles/36000180682-code-samples

Hallo,

bei mir läuft das seit heute perfekt. Dabei bin ich auch auf einige Fehler in der Doku gekommen:

1. worm_tse_listRegisteredClients läuft auch ohne vorherigen Admin Login korrekt

2. das hat nur funktioniert, nachdem ich die ClientID von const char* auf const unsigned char* umgestellt habe (bei allen Funktionen). Mit char habe ich nur das erste Zeichen der ClientID zurückbekommen.

Ich habe nur Delphi-Code im Angebot.


Struktur der Rückgabedaten:

WormClientArray = Array[1..16, 1..31] of AnsiChar;
WormClients = record
public
  var amount: Integer;
  var clientIds: WormClientArray;
end;

Die Definition des Befehls (Windows 32bit stdcall):

TWorm_tse_listRegisteredClients = function(context: IntPtr; toSkip: Integer; out clients: WormClients): WormError; stdCall;

Wichtig: Definition und Zuweisung der bei setup etc zu übergebenden ClientID:

WormClientID: TBytes;  //nicht PAnsiChar etc.
...
WormClientID := TEncoding.ASCII.GetBytes('442983K-710');

Anwendung des Befehls:

  

var
  WErr: WormError;
  WC: WormClients;
  i, j: Integer;
  cl: String;
begin
  WErr := worm_tse_listRegisteredClients(WormContext, 0, WC);
  //Fehlerbehandlung...
  for i := 1 to WC.amount do //nicht wie in der Doku i:=1 to amount-1 !!!
  begin
    cl := '';
    for j := 1 to 31 do
      cl := cl + WC.clientIds[i, j];
    Memo.Lines.Add(cl); //Ausgabe der fertig ausgelesenen ID wohin auch immer
  end;
end;

Läuft einwandfrei auch ohne vorherige Anmeldung als Admin, ein init reicht.

Hoffe das hilft auch den C-lern 


Funktioniert bei mir soweit

Hallo,

ich habe doch noch eine Merkwürdigkeit, und zwar egal ob mit stdcall oder mit der Window32 Version:

möchte ich die ClientID "SwissbitDemo" registrieren (egal ob mit register_clients oder im setup) bekomme ich die Meldung WORM_ERROR_INVALID_PARAMETER.

Ich hab das probiert, um mit der WormGUI kompatibel zu sein.


jeder abgewandelte String wie z.B. "SwissbitKDemo" geht in der Windows32 Version.

in der stccall Variante wirds noch schöner: Da registriert er statt dem angegebenen "123SwissbitDemo" eine längere Variante: "123SwissbitDemoogin". Übergebe ich "1234SwissbitDemo" wird daraus "1234SwissbitDemogin", hängt also 1 Zeichen weniger an weil die Vorgabe 1 Zeichen länger ist. Alles was kein SwissbitDemo drin hat, läuft bisher richtig (z.B. 44551287-K710).

Eine Bitte an den Support: werft da bitte einen Blick drüber. 

Ist das bei jemandem auch so?


Grüße Hans

Hallo,

hat sich zum Guten gewendet, schuld waren meine fehlenden Pointer sowohl im Abruf als auch im setup etc.

Mit dieser Definition läufts: 

function worm_tse_listRegisteredClients(context: PIntPtr; toSkip: Int32; out clients: WormClients): WormError; cdecl; external WormDLL;

 Die ClientID ist doch ein Pointer auf AnsiString:

var
WormClientID: AnsiString;
PWormClientID: PAnsiChar;
...
WormClientID := 'SwissbitDemo'; 
PWormClientID := PAnsiChar(WormClientID);

Grüße,

Hans

Hallo,

auch wir haben unseren Fehler gefunden. In der Dokumentation sieht es so aus als würde ein Pointer auf ein WormInfo Objekt benötigt werden, dies wird durch den Namen "info" suggeriert: https://support.gastro-mis.de/support/solutions/articles/36000180682-code-samples

Tatsächlich wird aber ein WormContext Objekt benötigt.

Anmelden oder Registrieren um einen Kommentar zu veröffentlichen