Die DLL-String-Funktion funktioniert nicht auf Build 600 - Seite 2

 
gchrmt4:

Das Simulieren alter Ansi-String-Arrays ist unübersichtlich, aber dennoch möglich. (Dies hängt davon ab, dass die DLL sich gut benimmt, insbesondere wenn sie Daten an MQL4 zurückgibt, indem sie den Inhalt des Arrays ändert. Ich habe dies nur mit dem C++-Beispielcode unten getestet, nicht mit etwas Realistischerem wie der MySql-Bibliothek).

Zum Beispiel funktioniert der obige Code mit der folgenden DLL, die eine Message-Box für jeden String in einem Array macht und dann die Zeichenfolge vor der Rückkehr zu MT4 umkehrt:


Ich kann gar nicht beschreiben, wie hilfreich Ihre Snippets sind. Vielen Dank dafür! Ich habe einen MySQL-Wrapper in reinem MQL4 (für die UNICODE-Version) geschrieben, der mit libmysql.dll (ANSI) kommuniziert und dabei Techniken verwendet, die Sie erwähnt haben, sowie Techniken, die ich in der EAX MySQL-Bibliothek (MQL5) gefunden habe.

Ich würde wirklich zu schätzen wissen, wenn Sie einen Blick auf meinen Code dort nehmen könnte und lassen Sie mich wissen, über Dinge zu verbessern oder dazu beitragen, wie ich bin ziemlich sicher, es könnte verbessert werden.

 

gchrmt4,

Können Sie mir bitte zeigen, wie ich eine Zeichenkette durch einen DLL-Funktionsaufruf übergeben kann, oder mich auf einen Beispielcode verweisen?

Was ich suche, ist die Bestätigung, dass ich einen Aufruf wie tun kann:

#import

int call_a_string_function(string this_is_a_string);

#import

...

...

string foo1 = "dies ist ein string";

int retruncode = call_a_string_function(foo1);

wie würde dann der C-Code für die obige Funktion aussehen? Ich bin gerade auf der Suche nach einem Beispiel für eine Routine.

z.B..

int call_a_string_function(char *this_is_a_string);

usw.

Einige Leute sagen, man solle ein Array oder ein char-Array usw. verwenden. Ich bin auf der Suche nach einer Klarstellung. Nur ein einfaches Beispiel für den besten Ansatz, da Sie Speicherverluste usw. erwähnt haben.

Grüße

gorick

 
gorick:

gchrmt4,

Können Sie mir bitte zeigen, wie ich eine Zeichenkette durch einen DLL-Funktionsaufruf übergeben kann, oder mich auf einen Beispielcode verweisen?

Was ich suche, ist die Bestätigung, dass ich einen Aufruf wie tun kann:

#import

int call_a_string_function(string this_is_a_string);

#import

...

...

string foo1 = "dies ist ein string";

int retruncode = call_a_string_function(foo1);

wie würde dann der C-Code für die obige Funktion aussehen? Ich bin gerade auf der Suche nach einem Beispiel für eine Routine.

z.B..

int call_a_string_function(char *this_is_a_string);

usw.

Manche Leute sagen, man solle ein Array oder ein char-Array usw. verwenden. Ich bin auf der Suche nach einer Klarstellung. Nur ein einfaches Beispiel für den besten Ansatz, da Sie Speicherverluste usw. erwähnt haben.

Grüße

gorick

Siehe diesen Artikel https://www.mql5.com/en/articles/18
 

Ja, danke dafür. Wirklich gut präsentiert und was ich erwartet hatte. Allerdings scheine ich Probleme mit Strings zu haben.

Ich habe ein Beispiel aus diesem Dokument in C erstellt, z.B. unten, um einen String-Wert als Eingabe zu akzeptieren und ihn in eine Datei zu schreiben:

#define  WIN32_LEAN_AND_MEAN
#include <windows.h>

#define  EXPORT extern "C" __declspec (dllexport)

//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
EXPORT void __stdcall GetStringValue(wchar_t *spar)
{
char abc[20];
strcpy(abc,"foooooooooooo1");
printf("GetStringValue \"%s\"\n",spar);
FILE *fp;
fp=fopen("fooerr.txt", "w");
fprintf(fp, "These are the string values: %s %s\n\n", spar, abc);
fclose(fp);
}

Ich schreibe die Werte zur Überprüfung in eine Datei.

MQL ist wie folgt:

 #property indicator_chart_window

#include <stderror.mqh>
#include <stdlib.mqh>

#import "myDLL.dll"

void GetStringValue(string instring);

#import

int init()
{

string instring = "Rick wrote this";

GetStringValue(instring);

return(0);
} // init

Die Dateiausgabe ist wie folgt:

Dies sind die String-Werte: R foooooooooooooo1

Es wird nur das "R" oder das erste Zeichen des übergebenen Strings zurückgegeben? Das "foooooooooooo1" wurde nur eingefügt, um zu überprüfen, ob ich richtig drucke.

Hat jemand eine Idee, was ich falsch mache?

 
gorick:

Ja, danke dafür. Wirklich gut präsentiert und was ich erwartet hatte. Allerdings scheine ich Probleme mit Strings zu haben.

Ich habe ein Beispiel aus diesem Dokument in C erstellt, z.B. unten, um einen String-Wert als Eingabe zu akzeptieren und in eine Datei zu schreiben:

<entfernt>

Bitte benutzen Sie die SRC-Schaltfläche, um den Code zu posten . . .
 
gorick:

Hat jemand eine Idee, was ich falsch mache?

Das Problem liegt in Ihrem C-Code, nicht in MQL4.

%s in printf() bedeutet "Ansi-String". Sie müssen %ls verwenden

 
gorick:

Ja, danke dafür. Wirklich gut präsentiert und was ich erwartet hatte. Allerdings scheine ich Probleme mit Strings zu haben.

Ich habe ein Beispiel aus diesem Dokument in C erstellt, z.B. unten, um einen String-Wert als Eingabe zu akzeptieren und ihn in eine Datei zu schreiben:

Ich schreibe die Werte zur Überprüfung in eine Datei.

MQL ist wie folgt:

Die Ausgabe der Datei ist wie folgt:

Dies sind die String-Werte: R foooooooooooooo1

Es wird nur das "R" oder das erste Zeichen des übergebenen Strings zurückgegeben? Das "foooooooooooo1" wurde nur eingefügt, um zu überprüfen, ob ich richtig drucke.

Hat jemand eine Idee, was ich falsch mache?


Hallo,

Bitte verwenden Sie die SRC-Schaltfläche, wenn Sie Code posten. Vielen Dank.


Dieses Mal habe ich ihn für Sie bearbeitet.

 
angevoyageur:

Hallo,

Bitte verwenden Sie die SRC-Schaltfläche, wenn Sie den Code posten. Ich danke Ihnen.


Dieses Mal habe ich ihn für Sie bearbeitet.


Tut mir leid, Leute, ich bin wirklich neu, dass ich hier schreibe.

Danke für Ihren Beitrag, ich bin Ihnen wirklich dankbar.

Dies bedeutet, dass alle vorhandenen Beispiele nicht korrekt sind. Man muss Unicode verwenden. Da ich noch sehr neu in der Programmierung von DLLs bin, habe ich erst vor kurzem ganz von vorne angefangen, also habe ich mich stark auf die vorhandenen Beispiele verlassen. Außerdem habe ich zufällig zur gleichen Zeit mit dem 600er Build angefangen.

Wenn Sie dies schon lange tun, nehme ich an, dass Sie sich der Situation vollkommen bewusst sind. Ich bin es leider nicht, da ich nur Bruchstücke von Informationen und Ratschlägen in diesem Forum erhalte.

Ich entschuldige mich für meine Unwissenheit.

Mit freundlichen Grüßen und Dank

 
Leute,

Da ihr mir alle geholfen habt, bin ich froh, meinen Code zu teilen, der eine Verbindung zu Oracle DB herstellt.

Das Problem ist, dass der Oracle Pro*C Precompiler und Oracle mit Unicode umgehen können, aber es gibt Einschränkungen, wo die Konstrukte verwendet werden können. Um sich anzumelden, müssen die Strings in Ascii sein. Nachfolgend ist der Code für die Anmeldung bei der DB über einen DLL-Aufruf aufgeführt.

Wenn jemand Vorschläge hat, was man besser machen könnte, lassen Sie es mich bitte wissen.

Ich danke Ihnen nochmals.

EXPORT int  __stdcall oracle_connect(char *connect1[], char *connect2[], char *connect3[])
{
   EXEC SQL BEGIN DECLARE SECTION;
   VARCHAR     username[UNAME_LEN];  /* VARCHAR is an Oracle-supplied struct */
   varchar     password[PWD_LEN];    /* varchar can be in lower case also. */
   varchar     dbstring[DBSTRING_LEN];
   EXEC SQL END DECLARE SECTION;

   /* Connect to ORACLE--
    * Copy the username into the VARCHAR.
    * Set the length component of the VARCHAR.
    
    strncpy((char *) username.arr, connect1, UNAME_LEN);
    username.len = strlen((char *) username.arr);
    strncpy((char *) password.arr, connect2, PWD_LEN);
    password.len = strlen((char *) password.arr);
    strncpy((char *) dbstring.arr, connect3, DBSTRING_LEN);
    dbstring.len = strlen((char *) dbstring.arr);
        
        EXEC SQL WHENEVER SQLERROR DO return(sqlca.sqlcode);
        EXEC SQL CONNECT :username IDENTIFIED BY :password USING :dbstring; 

/*    printf("\n\nConnected to ORACLE as user: %s\n", username.arr); */

    return(0);
}
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+

MQL4 code

#import "oraDLL.dll"
   int    oracle_connect(uchar user_name[], uchar user_pwd[], uchar db_service[]);
#import

extern string DBusername = "scott";
extern string DBpassword = "tiger";
extern string DBservice = "localhost/pdborcl";

int returncode;

int init()
{
  uchar user_name[], user_pwd[], db_service[];
  StringToCharArray(DBusername,user_name);
  StringToCharArray(DBpassword,user_pwd);
  StringToCharArray(DBservice,db_service);
  returncode = oracle_connect(user_name,user_pwd,db_service);
  Print("returncode = " + returncode);
}

 
gorick:
Leute,

Da ihr mir alle geholfen habt, bin ich froh, meinen Code zu teilen, der eine Verbindung zu Oracle DB herstellt.

Das Problem ist, dass der Oracle Pro*C-Precompiler und Oracle mit Unicode umgehen können, jedoch gibt es Einschränkungen, wo die Konstrukte verwendet werden können. Um sich anzumelden, müssen die Strings in Ascii sein. Nachfolgend ist der Code für die Anmeldung bei der DB über einen DLL-Aufruf aufgeführt.

Wenn jemand Vorschläge hat, was man besser machen könnte, lassen Sie es mich bitte wissen.

Ich danke Ihnen nochmals.

Vielen Dank an gorkk!
Grund der Beschwerde: