Paso de parámetros entre VB y VC++

Soy un programador de Visuasl Basic 6.0 y ahora estoy incursionando en Visual C++ 6.0.
Mi problema es el siguiente, tengo una rutina en Visual Basic 6.0 la cual es muy lenta,
y quiero escribirla en Visual C++ como una DLL y llamarla desde Visual Basic.
En visual C++ ya la probé y es infinitamente más rápida.
Mi duda es cómo declarar la función en Visual C++ para pasarle como parámetro
un arreglo de enteros por referencia, esto es, desde visual basic se debe de escribir algo así:
Declare Sub MiFuncion Lib "MyDll.dll" (ByRef arreglo() As Integer)
Dim arreglo(2) as intger
arreglo(0)=1
arreglo(1)=2
arreglo(2)=3
MiFuncion(arreglo)'Llamar a la funcion en Visual C++
Internamente los valores del arreglo serán modificados por Visual C++, y al salir
de la función el arreglo deberá de tener los nuevos valores.
En C++ he creado un proyecto Win32 Dynamyc-Link Library (tampoco se si este es mi mejor opción)
Y he declarado la función para recibir un arreglo de enteros por referencia de varias formas y
ninguna de ellas me funciona, he aquí algunas de ellas:
PUBLIC (void) MiFuncion(int arreglo[])
{
arreglo[0]=100;
arreglo[1]=200;
arreglo[2]=300;
}
PUBLIC (void) MiFuncion(int *arreglo[])
{
*arreglo[0]=100;
*arreglo[1]=200;
*arreglo[2]=300;
}
PUBLIC (void) MiFuncion(int *arreglo)
{
*arreglo=100;//este es un apuntador a entero sin emabrgo
//de esta forma no se como accesar a cada elemento del arreglo
}

2 Respuestas

Respuesta
1
PUBLIC (void) MiFuncion(int arreglo[]), aquí estás pasando un arreglo (array o vector) de enteros por valor, no por referencia. De esta forma, al salir de la función los valores que tú hayas puesto con arreglo[0]=100; no se conservan, porque los has guardado en una caopia que se destruye al salir de la función.
PUBLIC (void) MiFuncion(int *arreglo[]), esto es un vector de punteros a enteros. Al hacer *arreglo[0]=100; estás diciendo que coja el puntero que tienes en la posición cero (todavía no sabes qué hay ahí) y que donde esté apuntando que valga 0, con lo que estás barriendo posiciones aleatorias de la memoria. Aquí lo que puedes guardar son los punteros a enteros, por ejemplo arreglo[0]=&variable0;.
PUBLIC (void) MiFuncion(int *arreglo), esto es un puntero a un entero: te podría servir. *arreglo=100; *(arreglo+1)=200; Ten en cuenta que tú no has reservado memoria para el vector, por lo que si le pasas un vector de 10 elementos, sólo puedes tener acceso a esos elementos. Con esto quiero decir que además del vector, le tienes que pasar el tamaño del vector para que no accedas más allá de la memoria que has reservado.
En general la lectura de las declaraciones en C/C++ es derecha, izquierda:
1.- int arreglo[] es array de enteros
2.- int *arreglo[] es array de int *, es decir, array de punteros a int
3.- int *arreglo es un puntero a enteros
4.- int (*arreglo)[] es un puntero a un array de enteros (que es lo que tú quieres). Los paréntesis fuerzan que primero sea lo que está incluido en ellos. Se accede como (*arreglo)[2]=200; que quiere decir: donde apunta arreglo, toma el elemento 2 y lo igualas a 200.
Hasta aquí precioso, pero ... te recomiendo que no utilices estas cosas, son demasiado primitivas y por lo tanto susceptibles de errores: errores humanos al codificar, errores en entorno multihebra o multiprocesador (no puedes evitar que se acceda al mismo elemento por dos hebras al mismo tiempo), o incomodidades para redimensionar el vector como tú desees.
Solución: STL Standard Template Library. Como su propio nombre indica es estándar. Eso quiere decir que lo tienes en todos los compiladores y en todas las plataformas: puedes contar siempre con ello.
Aplicación: En tu caso sería utilizar un vector de enteros
#include <vector>
std::vector< int > miVector; miVector[2] = 200; Eso externamente a tu función y tu función yo la haría así;
PUBLIC (void) MiFuncion(std::vector<int> &arreglo) {
arreglo[2] = 300;
}
Una referencia a un vector de enteros. Así estás trabajando directamente con tu vector. El número de elementos que tienes es arreglo. Size(), para insertar arreglo. insert(valorNuevo); y para borrar el último arreglo. pop_back(). Si no tienes problemas con el inglés esta es la página oficial de STL: http://www.sgi.com/tech/stl/
De todas formas en internet hay mucho escrito sobre la STL.
Para recorrer el vector escribiendo utiliza
std::vector<int>::iterator iter=arreglo.begin();
while (iter!=arreglo.end()) {
*iter = 7;
iter++;
}
Si lo que vas a hacer es leer es preferible que utilices std::vector<int>::const_iterator y todo lo demás igual.
std::vector<int>::const_iterator iter=arreglo.begin();
while (iter!=arreglo.end()) {
printf("%d\n",*iter);
iter++;
}
Si prefieres eliminar el namespace haz lo siguiente. Pon al principio
#include <vector>
#using namespace std
Ya puedes eliminar std y hacer por ejemplo:
vector<int> miVector; // miVector es un vector de enteros. ¿Parece claro, no?
En fin. Espero que te haya sido de ayuda.
Un saludo desde Sevilla (España)
Juan Luis Jiménez Lillo
www.juan-luis.com
Respuesta
1
Creo que la forma más correcta es la ultima.
El modo de acceder a los elementos es por ejemplo como harías con un array
arreglo[0] = 100; // Primer elemento
arreglo[1] = 200; // Segundo elemento
...

Añade tu respuesta

Haz clic para o

Más respuestas relacionadas