DLL string function does not work on Build 600 - page 2

 
gchrmt4:

Simulating old Ansi string arrays is messy, but still possible. (This is going to depend on the DLL being well-behaved, particularly if it passes data back to MQL4 by altering the contents of the array. I've only tested this against the example C++ code at the bottom, not against something more realistic like MySql library.)

For example, the above code works with the following DLL which does a message box for each string in an array and then reverses the string before returning to MT4:


I just can't explain how helpful your snippets are. Thank you so much! I've went ahead and wrote a MySQL wrapper in pure MQL4 (for UNICODE version) that communicates with libmysql.dll (ANSI) using techniques you mentioned and techniques I found in EAX MySQL library (MQL5).

I'd really appreciate if you could take a look at my code there and let me know about things to improve or contribute to it as I'm pretty sure it could be improved.

 

gchrmt4,

Can you please show me how I can pass a string through a DLL function call, or point me to some sample code?

What I am looking for is confirmation that I can do a call such as:

#import

int call_a_string_function(string this_is_a_string);

#import

...

...

string foo1 = "this is a string";

int retruncode = call_a_string_function(foo1);

then what would the C code look like for the above function? I am just looking for the routine example.

e.g.

int call_a_string_function(char *this_is_a_string);

etc

Some people say to use an array or a char array etc. I am looking for some clarification. Just a simple sample on the best approach as you have mentioned memory leakage etc.

regards

gorick

 
gorick:

gchrmt4,

Can you please show me how I can pass a string through a DLL function call, or point me to some sample code?

What I am looking for is confirmation that I can do a call such as:

#import

int call_a_string_function(string this_is_a_string);

#import

...

...

string foo1 = "this is a string";

int retruncode = call_a_string_function(foo1);

then what would the C code look like for the above function? I am just looking for the routine example.

e.g.

int call_a_string_function(char *this_is_a_string);

etc

Some people say to use an array or a char array etc. I am looking for some clarification. Just a simple sample on the best approach as you have mentioned memory leakage etc.

regards

gorick

See this article https://www.mql5.com/en/articles/18
 

Yes, thanks for that. Really well presented and what I expected. However, I seem to be having issues with strings.

I created a sample from that document in C, e.g below, to accept a string value as input and write it to a file:

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

I write the vales to a file to check.

MQL is as follows:

 #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

The file output is as follows:

These are the string values: R foooooooooooo1

It only returns the "R" or first character of the passed string? The "foooooooooooo1" was inserted just to check that I am printing correctly.

Does anyone have an idea of what I am doing wrong?

 
gorick:

Yes, thanks for that. Really well presented and what I expected. However, I seem to be having issues with strings.

I created a sample from that document in C, e.g below, to accept a string value as input and write it to a file:

<removed>

Please use the SRC button to post code . . .
 
gorick:

Does anyone have an idea of what I am doing wrong?

The issue is in your C code, not in MQL4.

%s in printf() means "Ansi string". You need to use %ls

 
gorick:

Yes, thanks for that. Really well presented and what I expected. However, I seem to be having issues with strings.

I created a sample from that document in C, e.g below, to accept a string value as input and write it to a file:

I write the vales to a file to check.

MQL is as follows:

The file output is as follows:

These are the string values: R foooooooooooo1

It only returns the "R" or first character of the passed string? The "foooooooooooo1" was inserted just to check that I am printing correctly.

Does anyone have an idea of what I am doing wrong?


Hello,

Please use the SRC button when you post code. Thank you.


This time, I edited it for you.

 
angevoyageur:

Hello,

Please use the SRC button when you post code. Thank you.


This time, I edited it for you.


Sorry guys, really new to posting here.

Thanks for your input, I am really grateful.

What this implies is that all the existing samples are not accurate. One has to use unicode. As I am very new to programming DLLs I started from scratch just recently, so I relied heavily on the samples given. Also, I happened to start using the 600 build at the same time.

If you have been doing this for a long time, I'd imagine that you are completely aware of the situation. I unfortunately am not, only getting snippets of information and advice in this forum.

I apologise for my ignorance.

regards and thanks

 
People,

Because you have all helped me I am happy to share my code, which does a connection to Oracle DB.

The issue is that the Oracle Pro*C precompiler and oracle can handle unicode, however there are limitations to where the constructs can be used. To login, the strings have to be ascii. Below is the code to login to the DB from a DLL call.

If anyone has any suggestions on what to do better please let me know.

I thank you again.

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

Because you have all helped me I am happy to share my code, which does a connection to Oracle DB.

The issue is that the Oracle Pro*C precompiler and oracle can handle unicode, however there are limitations to where the constructs can be used. To login, the strings have to be ascii. Below is the code to login to the DB from a DLL call.

If anyone has any suggestions on what to do better please let me know.

I thank you again.

Thank you very much gorkk!