Строковая функция DLL не работает на Build 600 - страница 2

 
gchrmt4:

Имитация старых строковых массивов Ansi сложна, но все же возможна. (Это зависит от того, насколько хорошо ведет себя DLL, особенно если она передает данные обратно в MQL4, изменяя содержимое массива. Я проверил это только на примере C++ кода внизу, а не на чем-то более реалистичном, как библиотека MySql).

Например, приведенный выше код работает со следующей DLL, которая делает окно сообщения для каждой строки в массиве, а затем меняет строку на противоположную перед возвратом в MT4:


Я просто не могу объяснить, насколько полезны ваши сниппеты. Огромное спасибо! Я пошел дальше и написал обертку MySQL на чистом MQL4 (для версии UNICODE), которая взаимодействует с libmysql.dll (ANSI), используя методы, которые вы упомянули, и методы, которые я нашел в библиотеке EAX MySQL (MQL5).

Я был бы очень признателен, если бы вы взглянули на мой код и дали мне знать о том, что можно улучшить или внести свой вклад в него, так как я уверен, что его можно улучшить.

 

gchrmt4,

Не могли бы вы показать мне, как я могу передать строку через вызов функции DLL, или указать мне на пример кода?

Мне нужно подтверждение того, что я могу выполнить вызов, например:

#import

int call_a_string_function(string this_is_a_string);

#import

...

...

string foo1 = "это строка";

int retruncode = call_a_string_function(foo1);

тогда как бы выглядел код на C для вышеупомянутой функции? Я просто ищу пример рутины.

например.

int call_a_string_function(char *this_is_a_string);

и т.д.

Некоторые люди говорят, что нужно использовать массив или массив char и т.д. Я ищу некоторые разъяснения. Просто простой пример наилучшего подхода, поскольку вы упомянули об утечке памяти и т.д.

с уважением

горик

 
gorick:

gchrmt4,

Не могли бы вы показать мне, как я могу передать строку через вызов функции DLL, или указать мне на пример кода?

Мне нужно подтверждение того, что я могу выполнить вызов, например:

#import

int call_a_string_function(string this_is_a_string);

#import

...

...

string foo1 = "это строка";

int retruncode = call_a_string_function(foo1);

тогда как бы выглядел код на C для вышеупомянутой функции? Я просто ищу пример рутины.

например.

int call_a_string_function(char *this_is_a_string);

и т.д.

Некоторые люди говорят, что нужно использовать массив или массив char и т.д. Я ищу некоторые разъяснения. Просто простой пример наилучшего подхода, поскольку вы упомянули об утечке памяти и т.д.

с уважением

горик

См. эту статью https://www.mql5.com/en/articles/18
 

Да, спасибо за это. Действительно хорошо представлено и то, что я ожидал. Однако, похоже, у меня проблемы со строками.

Я создал пример из этого документа на C, например, ниже, чтобы принять строковое значение в качестве входного и записать его в файл:

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

Я записываю значения в файл для проверки.

MQL выглядит следующим образом:

 #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

Файл выводится следующим образом:

Вот строковые значения: R foooooooooooooooooooooooo1

Он возвращает только "R" или первый символ переданной строки? "foooooooooooooooooooooooo1" был вставлен только для того, чтобы проверить, что я печатаю правильно.

Есть ли у кого-нибудь идеи, что я делаю неправильно?

 
gorick:

Да, спасибо за это. Действительно хорошо представлено и то, что я ожидал. Однако, похоже, у меня проблемы со строками.

Я создал пример из этого документа на C, например, ниже, чтобы принять строковое значение в качестве входного и записать его в файл:

<удалено>

Пожалуйста, используйте кнопку SRC для размещения кода . . .
 
gorick:

Есть ли у кого-нибудь идея, что я делаю неправильно?

Проблема в вашем коде на C, а не в MQL4.

%s в printf() означает "строка Ansi". Вам нужно использовать %ls

 
gorick:

Да, спасибо за это. Действительно хорошо представлено и то, что я ожидал. Однако, похоже, у меня проблемы со строками.

Я создал пример из этого документа на C, например, ниже, чтобы принять строковое значение в качестве входного и записать его в файл:

Я записываю значения в файл для проверки.

MQL выглядит следующим образом:

Выход файла выглядит следующим образом:

Вот строковые значения: R foooooooooooooooooooooooo1

Он возвращает только "R" или первый символ переданной строки? "foooooooooooooooooooooooo1" был вставлен только для того, чтобы проверить, что я печатаю правильно.

Есть ли у кого-нибудь идеи, что я делаю неправильно?


Здравствуйте,

Пожалуйста, используйте кнопку SRC, когда публикуете код. Спасибо.


На этот раз я отредактировал его для вас.

 
angevoyageur:

Здравствуйте,

Пожалуйста, используйте кнопку SRC, когда публикуете код. Спасибо.


На этот раз я отредактировал его для вас.


Извините, ребята, я действительно новичок в написании сообщений.

Спасибо за ваш вклад, я действительно благодарен.

Из этого следует, что все существующие примеры не являются точными. Нужно использовать юникод. Поскольку я очень новичок в программировании DLL, я начал с нуля совсем недавно, поэтому я в значительной степени полагался на приведенные примеры. Кроме того, так получилось, что я начал использовать сборку 600 в то же время.

Если вы занимаетесь этим долгое время, я полагаю, что вы полностью осведомлены о ситуации. К сожалению, это не так, я получаю только отрывочную информацию и советы на этом форуме.

Я прошу прощения за свое невежество.

с уважением и благодарностью

 
Люди,

Поскольку вы все мне помогли, я рад поделиться своим кодом, который делает соединение с Oracle DB.

Проблема в том, что прекомпилятор Oracle Pro*C и oracle могут работать с юникодом, но есть ограничения на то, где можно использовать конструкции. Чтобы войти в систему, строки должны быть ascii. Ниже приведен код для входа в БД из вызова DLL.

Если у кого-нибудь есть предложения, как сделать лучше, пожалуйста, дайте мне знать.

Еще раз благодарю вас.

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:
Люди,

Поскольку вы все мне помогли, я рад поделиться своим кодом, который делает соединение с Oracle DB.

Проблема в том, что прекомпилятор Oracle Pro*C и oracle могут работать с юникодом, но есть ограничения на то, где можно использовать конструкции. Чтобы войти в систему, строки должны быть ascii. Ниже приведен код для входа в БД из вызова DLL.

Если у кого-нибудь есть предложения, как сделать лучше, пожалуйста, дайте мне знать.

Еще раз благодарю вас.

Большое спасибо gorkk!