A função de cadeia DLL não funciona no Build 600 - página 2

 
gchrmt4:

A simulação de antigas matrizes de corda Ansi é confusa, mas ainda assim possível. (Isto vai depender do bom comportamento da DLL, particularmente se ela passar os dados de volta para a MQL4 alterando o conteúdo da matriz. Eu só testei isto contra o exemplo do código C++ na parte inferior, não contra algo mais realista como a biblioteca MySql).

Por exemplo, o código acima funciona com a seguinte DLL que faz uma caixa de mensagem para cada string em um array e depois inverte a string antes de retornar ao MT4:


Só não consigo explicar o quanto seus trechos são úteis. Muito obrigado! Eu fui adiante e escrevi um wrapper MySQL em MQL4 puro (para a versão UNICODE) que se comunica com libmysql.dll (ANSI) usando técnicas que você mencionou e técnicas que encontrei na biblioteca EAX MySQL (MQL5).

Eu gostaria muito que você desse uma olhada no meu código e me informasse sobre coisas para melhorar ou contribuir para ele, pois tenho quase certeza de que poderia ser melhorado.

 

gchrmt4,

Você pode me mostrar como posso passar uma string através de uma chamada de função DLL, ou me apontar para algum código de amostra?

O que eu estou procurando é uma confirmação de que posso fazer uma chamada como essa:

#importar

int call_a_string_function(string this_is_a_string);

#importar

...

...

foo1 = "isto é um cordel";

int retruncode = call_a_string_function(foo1);

então como seria o código C para a função acima? Estou apenas procurando o exemplo de rotina.

Por exemplo

int call_a_string_function(char *this_is_a_string);

etc

Algumas pessoas dizem para usar um array ou um char array etc. Estou à procura de alguns esclarecimentos. Apenas uma simples amostra sobre a melhor abordagem, como você mencionou vazamento de memória, etc.

cumprimentos

gorick

 
gorick:

gchrmt4,

Você pode me mostrar como posso passar uma string através de uma chamada de função DLL, ou me apontar para algum código de amostra?

O que eu estou procurando é uma confirmação de que posso fazer uma chamada como essa:

#importar

int call_a_string_function(string this_is_a_string);

#importar

...

...

foo1 = "isto é um cordel";

int retruncode = call_a_string_function(foo1);

então como seria o código C para a função acima? Estou apenas procurando o exemplo de rotina.

Por exemplo

int call_a_string_function(char *this_is_a_string);

etc

Algumas pessoas dizem para usar um array ou um char array, etc. Estou à procura de alguns esclarecimentos. Apenas uma simples amostra sobre a melhor abordagem, como você mencionou vazamento de memória, etc.

cumprimentos

gorick

Veja este artigo https://www.mql5.com/en/articles/18
 

Sim, obrigado por isso. Realmente bem apresentado e o que eu esperava. Entretanto, parece que estou tendo problemas com as cordas.

Criei uma amostra desse documento em C, por exemplo, abaixo, para aceitar um valor de string como entrada e escrevê-lo em um arquivo:

#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);
}

Eu escrevo os vales em um arquivo para verificar.

MQL é o seguinte:

 #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

A saída do arquivo é a seguinte:

Estes são os valores das cadeias de caracteres: R foooooooooooo1

Ele só devolve o "R" ou primeiro caractere da corda passada? O "foooooooooooo1" foi inserido apenas para verificar se eu estou imprimindo corretamente.

Alguém tem uma idéia do que eu estou fazendo de errado?

 
gorick:

Sim, obrigado por isso. Realmente bem apresentado e o que eu esperava. Entretanto, parece que estou tendo problemas com as cordas.

Criei uma amostra desse documento em C, por exemplo, abaixo, para aceitar um valor de string como entrada e escrevê-lo em um arquivo:

<removido>

Por favor, use o botão SRC para postar o código . . .
 
gorick:

Alguém tem uma idéia do que eu estou fazendo de errado?

A questão está em seu código C, não na MQL4.

%s em printf() significa "Ansi string". Você precisa usar %ls

 
gorick:

Sim, obrigado por isso. Realmente bem apresentado e o que eu esperava. Entretanto, parece que estou tendo problemas com as cordas.

Criei uma amostra desse documento em C, por exemplo, abaixo, para aceitar um valor de string como entrada e escrevê-lo em um arquivo:

Eu escrevo os vales em um arquivo para verificar.

MQL é o seguinte:

A saída do arquivo é a seguinte:

Estes são os valores das cadeias de caracteres: R foooooooooooo1

Ele só devolve o "R" ou primeiro caractere da corda passada? O "foooooooooooo1" foi inserido apenas para verificar se eu estou imprimindo corretamente.

Alguém tem uma idéia do que eu estou fazendo de errado?


Olá,

Por favor, use o botão SRC quando você postar o código. Obrigado.


Desta vez, eu o editei para você.

 
angevoyageur:

Olá,

Por favor, use o botão SRC quando você postar o código. Obrigado.


Desta vez, eu o editei para você.


Desculpem rapazes, realmente novo para postar aqui.

Obrigado pela sua contribuição, estou muito agradecido.

O que isto implica é que todas as amostras existentes não são precisas. É preciso usar unicode. Como sou muito novo na programação de DLLs, comecei do zero há pouco tempo, por isso confiei muito nas amostras dadas. Além disso, por acaso comecei a usar os 600 build ao mesmo tempo.

Se você está fazendo isso há muito tempo, eu imagino que esteja completamente ciente da situação. Infelizmente não estou, apenas recebendo trechos de informações e conselhos neste fórum.

Peço desculpas por minha ignorância.

cumprimentos e agradecimentos

 
Pessoas,

Porque todos vocês me ajudaram, estou feliz em compartilhar meu código, que faz uma conexão com a Oracle DB.

A questão é que o pré-compilador e o oráculo Oracle Pro*C pode lidar com unicode, porém há limitações quanto ao local onde as construções podem ser usadas. Para fazer login, as cordas têm que ser ascii. Abaixo está o código para fazer o login no BD a partir de uma chamada de DLL.

Se alguém tiver alguma sugestão sobre o que fazer melhor, por favor me avise.

Agradeço novamente.

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:
Pessoas,

Porque todos vocês me ajudaram, estou feliz em compartilhar meu código, que faz uma conexão com a Oracle DB.

A questão é que o pré-compilador e o oráculo Oracle Pro*C pode lidar com unicode, porém há limitações quanto ao local onde as construções podem ser usadas. Para fazer login, as cordas têm que ser ascii. Abaixo está o código para fazer o login no BD a partir de uma chamada de DLL.

Se alguém tiver alguma sugestão sobre o que fazer melhor, por favor me avise.

Agradeço novamente.

Muito obrigado gorkk!
Razão: