Ayuda para resolver un problema con la importación de una función desde una dll - página 3

 

No agradezca :-). Lo harás todo tú mismo :-).

Explicado paso a paso:

.

#1 (prueba uno, no tienes que hacerlo ;-) :

En C++, crea una matriz con número de filas MAX_ROW = 5...10, columnas MAX_COL = 5...10 (números al azar).

Haz que se llene de datos de forma aleatoria.

.

#2 (prueba uno, no tienes que hacer ;-) : resuelve el siguiente problema:

La matriz del paso 1 debe representarse en forma unidimensional.

crear un array unidimensional double de tamaño=MAX_ROW*MAX_COL, donde los datos se almacenan según la fórmula

for(línea = 0 ... MAX_COL-1)

for(columna = 0 ... MAX_COL-1)

array[línea*MAX_COL + columna] = datos[línea][columna];

.

#3: resuelve el siguiente problema / como una función

Del paso (2) se obtiene un array unidimensional doble, el número de filas y columnas.

Debes poner los datos de este array en un objeto ap::real_2d_array

.

#4: Se obtiene el objeto ap::real_2d_array / como una función

Hay que convertirlo en un array unidimensional doble, obtener el número de filas y columnas.

.

#5 (prueba uno, no tienes que hacer ;-) :

Hay que convertir la matriz unidimensional en una matriz bidimensional (como en el paso 1).

Compare la matriz resultante con la matriz original del paso 1.

En caso de desajuste, resuélvelo.

.

Las principales funciones que se necesitarán son las funciones 3 y 4.

Pasos 1,2 = entrenamiento, tendrás que empaquetar los datos en Mql de esta manera, paso 5 = prueba.

.

En general, yo haría funciones para cada uno de los 5 pasos.

.

Transformación singular en Mql.

https://www.mql5.com/ru/code/7359

 

Gracias por el desglose detallado de cómo debe funcionar este algoritmo de descomposición singular. Los puntos 1 a 3 se aplican. El problema sigue siendo el punto 4, porque todavía no soy capaz de crear una dll que funcione con la función de exportación rmatrixsvd(...), como escribí antes,

por añadir externamente "C" bool __declspec(dllexport) __stdcall rmatrixsvd(...) al código original de C++, obtengo errores... Aunque si se compila sólo bool rmatrixsvd(...) no hay errores... pero lo que necesito es una función exportable... Ahí es donde se vuelve confuso...

Gracias por la ayuda.

 

En cuanto al punto 4 (y todos los demás). rmatrixsvd no tiene nada que ver.

Tampoco lo hace el algoritmo de descomposición singular. Estos elementos están relacionados con

para enviar/recibir datos desde/hacia Dll.

.

La función prototipo que se escribirá para el artículo. 4:

void Convertir_real_2d_array_a_doble(

const ap::real_2d_array & arr,

doble * datos,

int y líneas,

int y columnas

);

.

Es decir, tienes que aprender a obtener el número de filas, columnas y datos de ap::real_2d_array.

.

De esto:

const ap::real_2d_array & arr

---->>>

Consíguelo:

doble * datos,

int y líneas,

int y columnas

 

Muchas gracias de nuevo por su tiempo.

Una vez más he leído todos los posts con mucha atención y parece que por fin he descubierto :-) lo que hay que hacer.

De hecho, la propia función rmatrixsvd es una especie de "caballo de batalla" en este caso y no es necesario intentar exportarla,

sólo tienes que poner la carga en el carro a tiempo y luego descargarla ordenadamente en el lugar correcto cuando se entregue

a su destino, en sentido figurado. ¿Le he entendido bien ahora?

En otras palabras, necesito hacer estos convertidores de datos (3 y 4) en C++ y trabajar con ellos en MQL, es decir, deben ser declarados en MQL, y en DLL se

ser declarados como exportables, para que Metatrader pueda utilizarlos. ¿Entiendo bien mi problema?

Si es así, y creo que ahora te entiendo, es aún mejor, porque entonces no estaba seguro de cómo enlazar arrays 2D y 1D.

Además, no se puede declarar un array como un[ ][ ] en MQL, ¿verdad? Es decir, el array debería declararse al menos como a[ ][100]. ¿Es así? ¿O me equivoco?

Y esto no es muy conveniente porque no se sabe de antemano cuál será la dimensión de un array bidimensional, mientras que reservar memoria para un array por adelantado no es la mejor manera de hacerlo,

Pero en C++ no existe ese problema... Así, una matriz bidimensional puede llamarse figurativamente "goma". ¿Es así? ¿O también hay algunas sutilezas en C++?

También me gustaría preguntarle sobre Borland Builder 2009. ¿Tal vez no tenga tantos fallos como el 6º? ¿Es posible trabajar con él?

Porque alsu ha dicho que es un retrasado, que yo sepa. :-) Pero, por lo que he entendido, ¿programas con Visual Studio? ¿Está más fresco? ¿Y sin fallos? ¿Cuál es la última versión en este momento?

Me alegro de haber llegado al fondo de mi problema con su ayuda. Ahora intentaré ponerlo todo en práctica...

 
boysn >> :

Sobre todo porque no se puede declarar un array como un[ ][ ] en MQL, ¿verdad? Es decir, al menos deberías declararlo como un[ ][100]. ¿Es así? ¿O me equivoco?

Y esto no es muy conveniente porque no se sabe de antemano cuál será la dimensión de un array bidimensional, mientras que reservar memoria para un array por adelantado no es la mejor manera de hacerlo,

¡Genial! :-) Me alegro mucho de que el proceso llegue a alguna parte :-).

.

Por supuesto, puedes declarar arrays bidimensionales en Mql4.

Y de la misma manera se pueden importar funciones de la DLL

#importar miLib

void showMatrix(double & array[][], int rows, int cols);

#importar

.

Pero aquí hay un matiz: en C, declaramos una función que acepta un array unidimensional,

el número de filas y columnas void showMatrix(double *array, int rows, int cols);

Y la matriz funciona como una matriz unidimensional, cuyo direccionamiento se organiza en un bucle:

for(línea = 0 ... MAX_COL-1)
for(columna = 0 ... MAX_COL-1)
array[línea*MAX_COL + columna] = datos[línea][columna];

.

Es decir, Mql lanza un array bidimensional con un buffer continuo.

.

Sólo no pise el mismo rastrillo - las funciones del paso 3 y 4 se utilizan dentro de su Dll,

dentro de la función de interfaz del Dll-ins que tomará las matrices unidimensionales con número de filas/columnas de Mql.

Los convertirá a ap::real_2d_array, los pasará a rmatrixsvd

y pone el resultado en el búfer de salida, que debe tener la fila y la columna correctas

debe ser correcta.

.

El buffer de salida debe ser reservado de antemano, por supuesto - debe hacerse en Mql.

Si no conoces las dimensiones, mi opinión es que debes hacer

una matriz unidimensional de alta dimensionalidad, por ejemplo

doble fuera[2500];

y un array de un elemento para los valores de salida de las filas/columnas

doble raws[1];

doble cols[1];

.

Visual Studio es más genial. Especialmente con la Asistencia Visual. No sé cómo funciona el STL en Debuilder. Hay casi un 100% de problemas con Unicode.

La ayuda del Win SDK no se compara con la de MSDN. Se rumorea que para integrar con delphi el compilador Borland

para los pluses ha sufrido cambios no positivos.

.

Y trabajar con la memoria es un tema para una clase.

 

Todo parece estar teóricamente claro, me pondré a la implementación, y entonces veremos :-). "Los ojos tienen miedo, pero las manos hacen el trabajo..."

Gracias de nuevo por la valiosa orientación. Realmente me gustaría implementar este algoritmo... Como siempre, la idea está ya muy lejos estratégicamente, pero táctica y prácticamente

Tengo que ponerme al día. Espero poder hacerlo. Si tengo alguna pregunta, no duden en aconsejarme. Gracias.

 

Me gustaría aclarar una vez más sobre la dimensionalidad de las matrices dinámicas.

En MQL, un array unidimensional puede definirse como array[ ], y entonces cuando el programa conoce la dimensión del array N,

puedes utilizar la función ArrayResize(array, N). Un array bidimensional puede definirse sólo como array[ ][100], es decir, la segunda dimensionalidad

debe conocerse igualmente, y si no se conoce, debe tomarse el máximo para que sea suficiente en cualquier caso. Puede definir en MQL

El compilador no se quejará de ello, pero la función ArrayResize establece un nuevo tamaño en la primera dimensión del array ,

En MQL no existe esta función para la segunda dimensión. Si defines una matriz bidimensional array[N][M], el compilador devolverá un error diciendo

un número entero, es decir, la dimensionalidad debe estar definida de antemano, al menos la segunda dimensión del array.

¿Es lo mismo en C++? No hay forma de escapar de ello, ¿verdad? Una vez más me gustaría aclarar.

La descomposición singular utiliza la biblioteca AP para C++ (descripción en el archivo adjunto). Hay algunas funciones en él que, por lo que he entendido, resuelven

problemas de primera y segunda dimensión dinámica de las matrices. ¿Puedo utilizarlos en mi caso dentro de la DLL al escribir convertidores de datos?

void setbounds(int iLow1, int iHigh1, int iLow2, int iHigh2)
Asignar memoria para el array. Esto borra el contenido del antiguo array y libera la memoria asignada para él, luego asigna una nueva área de memoria separada con el tamaño de (iHigh1-iLow1+1)*(iHigh2-iLow2+1) elementos.
La numeración de los elementos en un nuevo array por la primera dimensión comienza con iLow1 y termina con iHigh1, lo mismo para la segunda dimensión.
El contenido del nuevo array no está definido.

También existe la siguiente función:

void setcontent(int iLow1, int iHigh1, int iLow2, int iHigh2, const T *pContent)
El método es similar al método setbounds(), salvo que el contenido de la matriz pContent[] se copia en ella después de la asignación de memoria.
La matriz pContent contiene una matriz bidimensional escrita línea por línea, es decir, el elemento [iLow1, iLow2] va primero, luego [iLow1, iLow2+1], etc.

Si he entendido bien, esta es exactamente la función que necesito, es decir, convierte un array unidimensional en uno bidimensional, es decir, es esencialmente un conversor.

¿Lo he hecho bien?

 

Biblioteca AP para C++

 
Biblioteca AP para C++
Archivos adjuntos:
 

MQL : en la unidimensionalidad cambiamos la dimensión como queramos, sí. Luego obtenemos todo por índices (línea * MAX_COL + col).

En dos dimensiones, la 2ª dimensión es fija. Es decir, no podemos leer los elementos de la matriz [15][32] del array a[100][100].

.

Y te sugiero que compruebes cómo funcionan las funciones de la biblioteca AP.

No te detengas en el Dll. Escribe un exe, es más fácil de ejecutar y depurar.

Inserta una impresión de depuración.

Consejos sí puedo dar - pero para los consejos, hay que probarlos -.

escribir el código de prueba.

.

En cuanto al contenido de la matriz y las variables -no importa dónde-

mejor hacer una regla para inicializarlos a la fuerza, rígidamente.