Help with this DLL I am writing in VC++ to be used in VB 6 (Simple Code)

bignateyk

Lifer
Apr 22, 2002
11,288
7
0
ok, I want to write a DLL in visual c++ that just returns the numerical value of a position in an array passed into it thru visual basic...

Here is the C++ DLL Code:

---------------------------------------------------------------------------------------------------
Main.CPP
---------------------------------------------------------------------------------------------------
#define WIN32_LEAN_AND_MEAN // No MFC

#include <windows.h> // Standard Windows Include

INT APIENTRY APITest(int imageArray[])
{
int test = imageArray[4];
return test;
}


---------------------------------------------------------------------------------------------------
definitions.def
---------------------------------------------------------------------------------------------------
EXPORTS
APITest @1





Here is the visual basic code:

Private Declare Function TestMyDll Lib "vbdll.dll" Alias "APITest" (ByRef array2() As Integer) As Long

Private Sub Command1_Click()
On Error Resume Next
Dim x As Integer
Dim a(10) As Integer

For x = 0 To 10
a(x) = x
Next x

x = TestMyDll(a())
msgbox x
End Sub



Whenever I click command1, it either msgboxes "0" or a really big number like "25034745"

I am a beginner at this so I am probably not passing the array right or something...

Any ideas?

Thanks.
 

Descartes

Lifer
Oct 10, 1999
13,968
2
0
An integer in VB is a short in C. You're declaring an array of ints in the C++ side and an array of integers in the VB side. Since an int in C is 32-bits (on most platforms), the 16-bit array of integers in VB will cause each int in the array on the C side to get two extra bytes of the integer in the VB side. Consider this VB array:

[................][................][................][................]

An array of 16-bit integers. Now consider what the C APITest routine expects:

[................................][................................][................................][................................]

Make sense? If you had an array in VB like the following:

Dim nFoo(2) As Integer
nFoo(0) = 1
nFoo(1) = 1

Then you passed nFoo to APITest, the first element in the array passed on the C side would be 0x00010001, or 65537 in decimal: an overflow for a 16-bit integer.

Also note that in most cases, simply passing a short to a routine that expects an int will cause it to zero-extend, thus you're usually safe; however, such is not the case in the context of an array as you can't zero-extend an array composed of arbitrarily defined data types.

I hope that makes at least some sense. Kinda hard to articulate...
 

Descartes

Lifer
Oct 10, 1999
13,968
2
0
Change your declaration in VB to this:

Private Declare Function TestMyDll Lib "vbdll.dll" Alias "APITest" (ByRef array As Long) As Long

Then call the function like this:

Private Sub Command1_Click()
On Error Resume Next
Dim x As Integer
Dim a(10) As Integer

For x = 0 To 10
a(x) = x
Next x

x = TestMyDll(a(0))
msgbox x
End Sub

Sorry, I focused on the data type mismatch and neglected that part. That *should* get you going, but no guarantees :). The point is that you need to send the C++ function the address to the first element in the array. The only way to do this is to pass the first element in ByRef in VB.
 

bignateyk

Lifer
Apr 22, 2002
11,288
7
0
yeah that works now.

My next question is how to make a void that allows me to use several variables from it.

For example,


C++ Code:

void _stdcall imageSubtraction()
{

long number1 = 20;
long number 2 = 20;
bool q = true;
}


VB Code:

dim test as long
dim booltest as boolean
Call imageSubtraction()

booltest = q
if booltest = true then
test = number 1
end if

---------------------------------------------------

There isnt really a point to that code, but I need to know how I can use the variables from a void function.

I tried using the method above, but it wont return those variables to VB.
 

Descartes

Lifer
Oct 10, 1999
13,968
2
0
You can't alter the value of a variable if you don't pass it a pointer to its value. You need to declare a pointer to the variable in your function declaration. e.g.:

void foo(int *p)
{
*p = 1;
}

Then on the VB side you need to pass in the appropriate data type ByRef:

Declare Sub Foo Lib "vbdll.dll" (ByRef n As Long)

Dim i As Integer
i = 9
Call Foo(i)
' i now == 1

Do the equivalent for whatever data type you want to alter within the function you call.
 

bignateyk

Lifer
Apr 22, 2002
11,288
7
0
cool. thanks. Also, is there a c++ equivalent to "Exit Sub" ? I tried "return 0" but that only works in functions not voids.