Como pasar array bytes de Visual C++ a Visual Basic???

28/05/2010 - 13:40 por Inaki Luengas | Informe spam
Resulta que tengo hecha una DLL("Tester.dll") en Visual C++ 2005 con una
función definida:

LPBYTE __stdcall getImg()
{

LPBYTE lpBufferCam;

//Devuelve resultado actualizado de leer imagenes
return lpBufferCam;
}

La función en si devuelve un array de bytes de una imagen, como puedo hacer
la llamada desde VB 6.0 a dicha función y que obtenga dicho array de bytes?
Yo pruebo en un formulario de VB 6.0 con:

Private Declare Function getImg Lib "Tester.dll" () As Byte

Private Sub Command4_Click()

Dim arrData() As Byte

arrData() = getImg

End Sub

Pero me da error de tipos...

Alguna sugerencia.Muchas gracias de antemano.

Un saludo.
Iñaki Luengas

Preguntas similare

Leer las respuestas

#1 RFOG
28/05/2010 - 14:03 | Informe spam
Esto mejor iría en un foro de VB...

A ver si aparece Cholo y lo sabe...

On Fri, 28 May 2010 13:40:03 +0200, Inaki Luengas
wrote:

Mostrar la cita
Microsoft Visual C++ MVP => http://geeks.ms/blogs/rfog
La mayor declaración de amor es la que no se hace, el hombre que siente
mucho habla poco.
#2 Cholo Lennon
31/05/2010 - 02:06 | Informe spam
"RFOG" wrote in message news:
Mostrar la cita
Interesante pregunta antes del cierre del foro :-)
Ahora si, tomando la posta del amigo RFOG vamos a lo concreto:

Hay varias formas de encarar el asunto. Lo logico y politicamente correcto
seria hacer una clase COM en C++ usando por ejemplo ATL. De esta manera la
integracion entre VC++ y VB seria natural. Pero visto y considerando que se
tiene una funcion C el tema es el siguiente:

- VB maneja internamente los arrays como un tipo Windows SAFEARRAY. Este
ultimo a su vez se encapsula dentro de un tipo VARIANT cuando es pasado
entre objetos.
- VB no entiende el concepto de un puntero a algo tal como es usando en
C/C++

En base a lo anterior es imposible (desde mi punto de vista) mapear un
puntero a BYTE en un array de VB. Ademas si esto fuera posible surge otro
pregunta: quien libera la memoria del array? el codigo C/C++ o el codigo
VB? Esto queda fuera de discusion con el SAFEARRAY ya que es COM el
encargado de asignar y liberar su memoria.

Las alternativas son:

- (Como ya se dijo) Escribir una clase COM en C++ y consumirla desde VB
- Manipular el SAFEARRAY en C/C++ y pasarlo a VB (es algo similar al primer
punto, pero sin usar COM en la comunicacion C++/VB)
- Cambiar el punto de vista de quien crea el array: Crear el array en VB y
decirle al codigo C/C++ que lo llene. Para tu caso se me ocurre que esta
seria la mejor ya que es algo sencillo de hacer.

Tomando la 3er alternativa entonces tenemos:

[C/C++]
void __stdcall GetImg(LPBYTE pArray, LONG size)
{
// Llenar el pArray de tamano size
...
}


[VB]
Private Declare Sub GetImg Lib "TuDLL.dll" (ByRef vec As Byte, ByVal size As
Long)

Sub Test()
Dim vec(1 to 100) as Byte

GetImg vec(1), 100

...

End Sub

Como se puede ver, el puntero a array se declara como de tipo Byte pero por
referencia. De esta manera VB pasa la direccion que en este caso es la del
primero elemento del array. Una forma mas generica de llamar seria:

Private Sub CallGetImg(vec() As Byte)
GetImg vec(LBound(vec)), UBound(vec) - LBound(vec) + 1
End Sub

Entonces se tendria algo como:

Dim vec1(1 to 50) As Byte, vec2(45 to 58) As Byte, vec3(200) As Byte

CallGetImg vec1
CallGetImg vec2
CallGetImg vec3

Por ultimo, como el array lo crea VB, quizas debas agregar una funcion en tu
DLL para obtener el tamano necesario para el mismo. De esta manera te
aseguras que el codigo VB no va a pasar un array de tamano insuficiente al
codigo C/C++


Saludos


Cholo Lennon
Bs.As.
ARG
#3 RFOG
31/05/2010 - 09:33 | Informe spam
Vaya, yo pensaba que sí que había una forma... :-(


On Mon, 31 May 2010 02:06:17 +0200, Cholo Lennon
wrote:

Mostrar la cita
<snip>
Mostrar la cita
Microsoft Visual C++ MVP => http://geeks.ms/blogs/rfog
La mayor declaración de amor es la que no se hace, el hombre que siente
mucho habla poco.
#4 Cholo Lennon
31/05/2010 - 15:47 | Informe spam
On 31/05/2010 04:33, RFOG wrote:
Mostrar la cita
Ojo, aclaro "desde mi punto de vista" (si hay una usando un puntero
comun de C la verdad que no la conozco)

Eso si, si se usa un SAFAARRAY desde C/C++ no hay ningun problema y el
codigo VB es tan natural como:

Dim Arr() as Byte
Arr = GetImg()

De todas maneras con un poco de VB y con la funcion para obtener tamano
de la DLL se puede emular el codigo anterior sin usar SAFEARRAY ni COM
en C/C++. Modificando la anterior CallGetImg se tiene:

Declare Function GetSize Lib "TuDLL.dll" () As Long
Declare Sub GetImg Lib "TuDLL.dll" (ByRef vec As Byte, ByVal size As Long)

Function CallGetImg() As Byte()
Dim size As Long
size = DllGetSize()

ReDim vec(size) As Byte
GetImg vec(LBound(vec)), size

CallGetImg = vec
End Function

Sub Test()
Dim Arr() as Byte
Arr = CallGetImg()
...
End Sub


Saludos


Cholo Lennon
Bs.As.
ARG


Mostrar la cita
#5 langosta
31/05/2010 - 16:11 | Informe spam
"Cholo Lennon" escribió en el mensaje de
noticias news:
Mostrar la cita
La forma sucia sería cambiando el tipo de la función en la declaración
de VB a Long (LPBYTE es un cardinal de 32 bits) y, en la propia función
hacer un redim del array y un CopyMemory()

CopyMemory arr, GetImg

¿cuál será el tamaño del array?

Ahora, el no nos cuenta para qué necesita el array. Ok si desea
manipular la data, pero si sólo necesita el puntero para pasarlo a
alguna otra función (digamos, CreateDIBitmap), entonces el uso del array
carece de sentido.
Ads by Google
Search Busqueda sugerida